Udostępnij za pośrednictwem


Pierwszeństwo i kojarzenie

Pierwszeństwo i kojarzenie definiują kolejność stosowania operatorów. Operatory o wyższym prioryencie są najpierw powiązane z ich argumentami (operandami), natomiast 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 zgodny z prawą kojarzeniem.

Operatory

W poniższej tabeli wymieniono dostępne operatory w Q#programie , a także ich pierwszeństwo i kojarzenie. Wymieniono również dodatkowe modyfikatory i kombinatory , a powiązanie jest ściślejsze 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 .. Infix left 2
operator warunkowy ? \| Trójskładnikowych w prawo 3
logiczne OR or Infix left 4
operator logiczny AND and Infix left 5
bitowe OR \|\|\| Infix left 6
bitowe XOR ^^^ Infix left 7
bitowe AND &&& Infix left 8
Równości == Infix left 9
Nierówności != Infix left 9
mniejsze niż lub równe <= Infix left 10
mniejsze niż < Infix left 11
większe niż lub równe >= Infix left 11
większe niż > Infix left 11
przesunięcie w prawo >>> Infix left 12
przesunięcie w lewo <<< Infix left 12
dodawanie lub łączenie + Infix left 13
Odejmowania - Infix left 13
Mnożenie * Infix left 14
Dywizji / Infix left 14
modulo % Infix left 14
Potęgowanie ^ Infix w prawo 15
bitowe NOT ~~~ Prefiks w prawo 16
logiczne NOT not Prefiks w prawo 16
negative - Prefiks 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 obejmują operator zakresu w celu zapewnienia spójnego zachowania 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 z pierwszeństwem operatorów i modyfikatorów w odniesieniu do tego, jak ściśle kombinatory dostępu do elementów ([]i :: odpowiednio) i kombinatory wywołań ((, )) wiążą.

Opis Składnia Operator Łączność Pierwszeństwo
Kombinator wywołań ( ) n/d left 17
Adjoint functor Adjoint Prefiks w prawo 18
Kontrolowany funktor Controlled Prefiks w prawo 18
Odpakowywanie aplikacji ! Postfix left 19
Dostęp do nazwanego elementu :: n/d left 20
Dostęp do elementu tablicy [ ] n/d left 20
Funkcja lambda -> n/d w prawo 21
Operacja lambda => n/d 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ństwa zdefiniowane w powyższej tabeli, widać, że nawiasy wokół (Transformation(GetStatePrep())) są niezbędne do późniejszego operatora odpakowania, który ma zostać zastosowany do Transformation wartości, a nie do zwróconej operacji. Nawiasy nie są jednak wymagane w GetStatePrep()(arg)elemencie ; funkcje są stosowane od lewej do prawej, więc to wyrażenie jest równoważne .(GetStatePrep())(arg) Aplikacje functor nie wymagają również 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].