Pierwszeństwo i kojarzenie
Pierwszeństwo i kojarzenie definiują kolejność, w jakiej są stosowane operatory. Operatory o wyższym pierwszeństwie są najpierw powiązane ze swoimi argumentami (operandami), podczas gdy operatory o tym samym pierwszeństwie wiążą się w kierunku ich kojarzenia.
Na przykład wyrażenie 1+2*3
zgodnie z pierwszeństwem dodawania i mnożenia jest równoważne 1+(2*3)
funkcji i 2^3^4
równa 2^(3^4)
się, ponieważ wykładnik jest odpowiednikiem skojarzenia prawego.
Operatory
W poniższej tabeli wymieniono dostępne operatory w elemencie Q#, a także ich pierwszeństwo i kojarzenie. Wymieniono również dodatkowe modyfikatory i kombinatory oraz powiązano ściślej niż którykolwiek z tych operatorów.
opis | Składnia | Operator | Łączność | Pierwszeństwo |
---|---|---|---|---|
operator copy-and-update | w/ <- |
Trójskładnikowych | left | 1 |
operator zakresu | .. |
infiks | left | 2 |
operator warunkowy | ? \| |
Trójskładnikowych | w prawo | 3 |
logiczne OR | or |
infiks | left | 100 |
logiczne AND | and |
infiks | left | 5 |
bitowe OR | \|\|\| |
infiks | left | 6 |
bitowy XOR | ^^^ |
infiks | left | 7 |
bitowe AND | &&& |
infiks | left | 8 |
równość | == |
infiks | left | 9 |
nierówność | != |
infiks | left | 9 |
mniejsze niż lub równe | <= |
infiks | left | 10 |
mniejsze niż | < |
infiks | left | 11 |
większe niż lub równe | >= |
infiks | left | 11 |
większe niż | > |
infiks | left | 11 |
przesunięcie w prawo | >>> |
infiks | left | 12 |
przesunięcie w lewo | <<< |
infiks | left | 12 |
dodawanie lub łączenie | + |
infiks | left | 13 |
odejmowanie | - |
infiks | left | 13 |
mnożenie | * |
infiks | left | 14 |
dzielenie | / |
infiks | left | 14 |
modulo | % |
infiks | left | 14 |
Potęgowanie | ^ |
infiks | w prawo | 15 |
bitowe NOT | ~~~ |
przedrostek | w prawo | 16 |
logiczne NOT | not |
przedrostek | w prawo | 16 |
Minus | - |
przedrostek | w prawo | 16 |
Wyrażenia kopiowania i aktualizacji muszą mieć najniższy priorytet, aby zapewnić spójne zachowanie odpowiadającej instrukcji evaluate-and-reassign. Podobne zagadnienia są przechowywane dla operatora zakresu, aby zapewnić spójne zachowanie odpowiedniego wyrażenia kontekstowego.
Modyfikatory i kombinatory
Modyfikatory mogą być postrzegane jako specjalne operatory, które można stosować tylko do niektórych wyrażeń. Można przypisać im sztuczny pierwszeństwo, aby przechwycić swoje zachowanie.
Aby uzyskać więcej informacji, zobacz Wyrażenia.
Ten sztuczny pierwszeństwo znajduje się w poniższej tabeli wraz ze sposobem, w jaki pierwszeństwo operatorów i modyfikatorów odnosi się do sposobu ścisłego łączenia dostępu do elementów (]
[
i ::
odpowiednio) i łączenia wywołań ((
, )
) powiązania.
opis | Składnia | Operator | Łączność | Pierwszeństwo |
---|---|---|---|---|
Kombinator wywołań | ( ) |
nie dotyczy | left | 17 |
Adjoint functor | Adjoint |
przedrostek | w prawo | 18 |
Kontrolowany funktor | Controlled |
przedrostek | w prawo | 18 |
Odpakowywanie aplikacji | ! |
Postfix | left | 19 |
Dostęp do nazwanego elementu | :: |
nie dotyczy | left | 20 |
Dostęp do elementu tablicy | [ ] |
nie dotyczy | left | 20 |
Funkcja lambda | -> |
nie dotyczy | w prawo | 21 |
Operacja lambda | => |
nie dotyczy | w prawo | 21 |
Aby zilustrować implikacje przypisanych pierwszeństw, załóżmy, że masz operację DoNothing
jednostkową (zdefiniowaną w deklaracjach specjalizacji), wywoływaną GetStatePrep
operację zwracającą operację jednostkową i tablicę algorithms
zawierającą elementy typu Algorithm
zdefiniowane w następujący sposób
newtype Algorithm = (
Register : Qubit[],
Initialize : Transformation,
Apply : Transformation
);
newtype Transformation =
Qubit[] => Unit is Adj + Ctl;
Następnie wszystkie następujące wyrażenia są prawidłowe:
GetStatePrep()(arg)
(Transformation(GetStatePrep()))!(arg)
Adjoint DoNothing()
Controlled Adjoint DoNothing(cs, ())
Controlled algorithms[0]::Apply!(cs, _)
algorithms[0]::Register![i]
Patrząc na pierwszeństwo zdefiniowane w powyższej tabeli, można zobaczyć, że nawiasy wokół (Transformation(GetStatePrep()))
są niezbędne do późniejszego operatora odpakowania do zastosowania do Transformation
wartości, a nie zwróconej operacji.
Nawiasy nie są jednak wymagane w elemencie GetStatePrep()(arg)
; funkcje są stosowane od lewej do prawej, więc to wyrażenie jest równoważne .(GetStatePrep())(arg)
Aplikacje Functor również nie wymagają nawiasów wokół nich w celu wywołania odpowiedniej specjalizacji, ani tablicy ani nazwanych wyrażeń dostępu do elementów. W związku z tym wyrażenie arr2D[i][j]
jest całkowicie prawidłowe, podobnie jak algorithms[0]::Register![i]
.