Dela via


Prioritet och associativitet

Prioritet och associativitet definierar i vilken ordning operatorerna tillämpas. Operatorer med högre prioritet är bundna till sina argument (operander) först, medan operatorer med samma prioritet binder i riktning mot deras associativitet. Uttrycket 1+2*3 enligt prioriteten för addition och multiplikation är till 1+(2*3)exempel likvärdigt med , och 2^3^4 är lika 2^(3^4) med eftersom exponenteringen är höger associativ.

Operatorer

I följande tabell visas tillgängliga operatorer i Q#, samt deras prioritet och associativitet. Ytterligare modifierare och kombinatorer visas också och binder hårdare än någon av dessa operatorer.

Description Syntax Operator Associativitet Prioritet
copy-and-update-operator w/ <- Ternära vänster 1
range-operatorn .. Infix vänster 2
villkorsstyrd operator ? \| Ternära right 3
logisk OR or Infix vänster 4
logisk AND and Infix vänster 5
bitvis ELLER \|\|\| Infix vänster 6
bitvis XOR ^^^ Infix vänster 7
bitwise AND &&& Infix vänster 8
Jämställdhet == Infix vänster 9
Ojämlikhet != Infix vänster 9
mindre än eller lika med <= Infix vänster 10
mindre än < Infix vänster 11
större än eller lika med >= Infix vänster 11
större än > Infix vänster 11
höger skift >>> Infix vänster 12
vänster skift <<< Infix vänster 12
addition eller sammanfogning + Infix vänster 13
Subtraktion - Infix vänster 13
Multiplikation * Infix vänster 14
Division / Infix vänster 14
Modulus % Infix vänster 14
Exponentiering ^ Infix right 15
bitvis INTE ~~~ Prefix right 16
logiskt INTE not Prefix right 16
negativt - Prefix right 16

Kopierings- och uppdateringsuttryck måste nödvändigtvis ha den lägsta prioriteten för att säkerställa ett konsekvent beteende för motsvarande evaluate-and-reassign-instruktion. Liknande överväganden gäller för intervalloperatorn för att säkerställa ett konsekvent beteende för motsvarande kontextuella uttryck.

Modifierare och kombinerare

Modifierare kan ses som särskilda operatorer som endast kan tillämpas på vissa uttryck. De kan tilldelas en artificiell prioritet för att fånga upp deras beteende.

Mer information finns i Uttryck.

Den här artificiella prioriteten visas i följande tabell, tillsammans med hur prioriteten för operatorer och modifierare relaterar till hur nära objektåtkomstkombinatorer ([]respektive::) och anropskombinatorer ((, )) binder.

Description Syntax Operator Associativitet Prioritet
Samtalskombinator ( ) saknas vänster 17
Adjoint functor Adjoint Prefix right 18
Kontrollerad kultor Controlled Prefix right 18
Packa upp program ! Postfix vänster 19
Åtkomst till namngivet objekt :: saknas vänster 20
Åtkomst till matrisobjekt [ ] saknas vänster 20
Funktionen lambda -> saknas right 21
Åtgärd lambda => saknas right 21

För att illustrera konsekvenserna av de tilldelade prioriteterna antar vi att du har en enhetlig åtgärd DoNothing (enligt definitionen i Specialiseringsdeklarationer), en anropningsbarGetStatePrep som returnerar en enhetlig åtgärd och en matris algorithms som innehåller objekt av typen Algorithm som definieras på följande sätt

    newtype Algorithm = (
        Register : Qubit[],
        Initialize : Transformation,
        Apply : Transformation
    );

    newtype Transformation =
        Qubit[] => Unit is Adj + Ctl;

Följande uttryck är sedan giltiga:

    GetStatePrep()(arg)
    (Transformation(GetStatePrep()))!(arg)
    Adjoint DoNothing()
    Controlled Adjoint DoNothing(cs, ())
    Controlled algorithms[0]::Apply!(cs, _)
    algorithms[0]::Register![i]

Om du tittar på prioriteterna som definierats i tabellen ovan kan du se att parenteserna runt (Transformation(GetStatePrep())) är nödvändiga för att den efterföljande unwrap-operatorn ska tillämpas på värdet i stället för Transformation den returnerade åtgärden. Parenteser krävs dock inte i GetStatePrep()(arg); funktioner tillämpas från vänster till höger, så det här uttrycket motsvarar (GetStatePrep())(arg). Functor-program kräver inte heller parenteser runt dem för att anropa motsvarande specialisering, inte heller matris- eller namngivna objektåtkomstuttryck. Uttrycket arr2D[i][j] är alltså helt giltigt, liksom algorithms[0]::Register![i].