Accesso agli elementi
Q# supporta l'accesso agli elementi delle matrici e agli elementi nei tipi definiti dall'utente. In entrambi i casi, l'accesso è di sola lettura; Non è possibile modificare il valore senza creare una nuova istanza usando un'espressione di copia e aggiornamento.
Accesso a elementi di matrice e slicing di matrici
Data un'espressione di matrice e un'espressione di tipo Int
o Range
, è possibile creare una nuova espressione usando l'operatore di accesso agli elementi delle matrici costituito da [
e ]
.
Se l'espressione all'interno delle parentesi quadre è di tipo Int
, la nuova espressione contiene l'elemento della matrice in corrispondenza di tale indice.
Ad esempio, se arr
è di tipo Double[]
e contiene cinque o più elementi, arr[4]
è un'espressione di tipo Double
.
Se l'espressione all'interno delle parentesi quadre è di tipo Range
, la nuova espressione contiene una matrice di tutti gli elementi indicizzati dall'oggetto specificato Range
. Se è Range
vuoto, la matrice risultante è vuota.
Ad esempio,
let arr = [10, 11, 36, 49];
let ten = arr[0]; // contains the value 10
let odds = arr[1..2..4]; // contains the value [11, 49]
let reverse = arr[...-1...]; // contains the value [49, 36, 11, 10]
Nell'ultima riga dell'esempio il valore iniziale e finale dell'intervallo è stato omesso per praticità. Per altre informazioni, vedere Espressioni contestuali.
Se l'espressione di matrice non è un identificatore semplice, deve essere racchiusa tra parentesi per estrarre un elemento o una sezione.
Ad esempio, se arr1
e arr2
sono entrambe matrici di interi, un elemento dalla concatenazione verrebbe espresso come (arr1 + arr2)[13]
. Per altre informazioni, vedere Precedenza e associatività.
Tutte le matrici in Q# sono in base zero, ovvero il primo elemento di una matrice arr
è sempre arr[0]
.
In fase di esecuzione viene generata un'eccezione se l'indice o uno degli indici utilizzati per il sezionamento non rientra nei limiti della matrice, ad esempio se è minore di zero o maggiore o uguale alla lunghezza della matrice.
Accesso agli elementi per i tipi definiti dall'utente
Per altre informazioni su come definire tipi personalizzati contenenti uno o più elementi denominati o anonimi, vedere Dichiarazioni di tipo.
È possibile accedere agli elementi contenuti tramite il nome o la decostruzione, illustrati dalle istruzioni seguenti che possono essere usate come parte di un'implementazione di un'operazione o di una funzione:
let complex = Complex(1., 0.); // create a value of type Complex
let (re, _) = complex!; // item access via deconstruction
let im = complex::Imaginary; // item access via name
L'operatore di accesso agli elementi (::
) recupera gli elementi denominati, come illustrato nell'esempio seguente:
newtype TwoStrings = (str1 : String, str2 : String);
operation LinkTwoStrings(str : TwoStrings) : String {
let s1 = str::str1;
let s2 = str::str2;
return s1 + s2;
}
Mentre gli elementi denominati sono accessibili tramite il nome o tramite decostruzione, gli elementi anonimi sono accessibili solo tramite quest'ultima tecnica. Poiché la decostruzione si basa su tutti gli elementi contenuti, l'uso di elementi anonimi è sconsigliato quando questi elementi devono essere accessibili all'esterno dell'unità di compilazione in cui è definito il tipo.
L'accesso tramite decostruzione usa l'operatore unwrap (!
). L'operatore unwrap restituisce una tupla di tutti gli elementi contenuti, in cui la forma della tupla corrisponde a quella definita nella dichiarazione e una tupla di un singolo elemento equivale all'elemento stesso (vedere questa sezione).
Ad esempio, per un valore nested
di tipo Nested
definito come segue
newtype Nested = (Double, (ItemName : Int, String));
l'espressione nested!
restituisce un valore di tipo (Double, (Int, String))
.
L'operatore !
ha una precedenza inferiore rispetto a entrambi gli operatori di accesso agli elementi, ma ha una precedenza maggiore rispetto a qualsiasi altro operatore. Per un elenco completo delle precedenze, vedere Precedenza e associatività.