Dostęp do elementu
Q# obsługuje dostęp do elementów tablicy i elementów w typach zdefiniowanych przez użytkownika. W obu przypadkach dostęp jest tylko do odczytu; nie można zmienić wartości bez tworzenia nowego wystąpienia przy użyciu wyrażenia copy-and-update.
Dostęp do elementu tablicy i fragmentowanie tablic
Biorąc pod uwagę wyrażenie tablicy i wyrażenie typu Int
lub Range
, można utworzyć nowe wyrażenie przy użyciu operatora dostępu do elementu tablicy składającego [
się z i ]
.
Jeśli wyrażenie wewnątrz nawiasów jest typu Int
, nowe wyrażenie zawiera element tablicy w tym indeksie.
Jeśli na przykład arr
jest typu Double[]
i zawiera pięć lub więcej elementów, arr[4]
to wyrażenie typu Double
.
Jeśli wyrażenie wewnątrz nawiasów jest typu Range
, nowe wyrażenie zawiera tablicę wszystkich elementów indeksowanych przez określony Range
element . Jeśli pole jest puste, wynikowa Range
tablica jest pusta.
Na przykład
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]
W ostatnim wierszu przykładu wartość początkowa i końcowa zakresu została pominięta dla wygody. Aby uzyskać więcej informacji, zobacz Wyrażenia kontekstowe.
Jeśli wyrażenie tablicy nie jest prostym identyfikatorem, musi być ujęte w nawiasy w celu wyodrębnienia elementu lub wycinka.
Na przykład jeśli arr1
i arr2
są tablicami liczb całkowitych, element z łączenia zostanie wyrażony jako (arr1 + arr2)[13]
. Aby uzyskać więcej informacji, zobacz Pierwszeństwo i skojarzenie.
Wszystkie tablice w systemie Q# są oparte na zera, czyli pierwszym elementem tablicy arr
jest zawsze arr[0]
.
Wyjątek jest zgłaszany w czasie wykonywania, jeśli indeks lub jeden z indeksów używanych do fragmentowania znajduje się poza granicami tablicy, na przykład jeśli jest mniejszy niż zero lub większy lub równy długości tablicy.
Dostęp do elementów dla typów zdefiniowanych przez użytkownika
(Aby uzyskać więcej informacji na temat definiowania typów niestandardowych zawierających co najmniej jeden nazwany lub anonimowy element, zobacz Deklaracje typów).
Dostęp do zawartych elementów można uzyskać za pośrednictwem ich nazwy lub dekonstrukcji, ilustrowanej przez następujące instrukcje, które mogą być używane w ramach operacji lub implementacji funkcji:
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
Operator dostępu do elementu (::
) pobiera nazwane elementy, jak pokazano w poniższym przykładzie:
newtype TwoStrings = (str1 : String, str2 : String);
operation LinkTwoStrings(str : TwoStrings) : String {
let s1 = str::str1;
let s2 = str::str2;
return s1 + s2;
}
Chociaż nazwane elementy mogą być dostępne według ich nazwy lub za pośrednictwem dekonstrukcji, dostęp do elementów anonimowych można uzyskać tylko przez tę drugą. Ponieważ dekonstrukcja opiera się na wszystkich zawartych elementach, nie zaleca się używania elementów anonimowych, gdy te elementy muszą być dostępne poza jednostką kompilacji, w której typ jest zdefiniowany.
Dostęp za pośrednictwem dekonstrukcji korzysta z operatora unwrap (!
). Operator unwrap zwraca krotkę wszystkich zawartych elementów, gdzie kształt krotki jest zgodny z elementem zdefiniowanym w deklaracji, a pojedyncza krotka elementu jest równoważna samemu elementowi (zobacz tę sekcję).
Na przykład dla wartości nested
typu Nested
zdefiniowanego w następujący sposób
newtype Nested = (Double, (ItemName : Int, String));
wyrażenie nested!
zwraca wartość typu (Double, (Int, String))
.
!
Operator ma niższy pierwszeństwo niż oba operatory dostępu do elementów, ale wyższy pierwszeństwo niż jakikolwiek inny operator. Aby uzyskać pełną listę pierwszeństwa, zobacz Pierwszeństwo i skojarzenie.