Udostępnij za pośrednictwem


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].