Compartilhar via


Precedência e capacidade de associação

Precedência e associatividade definem a ordem na qual os operadores são aplicados. Operadores com precedência mais alta são associados a seus argumentos (operandos) primeiro, enquanto os operadores com a mesma precedência se associam na direção de sua associatividade. Por exemplo, a expressão 1+2*3 de acordo com a precedência de adição e multiplicação é equivalente a 1+(2*3)e 2^3^4 é igual a 2^(3^4) uma vez que a exponencialização é associativa à direita.

Operadores

A tabela a seguir lista os operadores disponíveis em Q#, bem como sua precedência e associatividade. Modificadores e combinadores de adicionais também são listados e associam mais apertados do que qualquer um desses operadores.

Descrição Sintaxe Operador Capacidade de associação Precedência
operador de cópia e atualização w/ <- Ternário Esquerda 1
operador de intervalo .. infix Esquerda 2
operador condicional ? \| Ternário Certo 3
or lógica or infix Esquerda 4
lógico AND and infix Esquerda 5
or bit a bit \|\|\| infix Esquerda 6
XOR bit a bit ^^^ infix Esquerda 7
AND bit a bit &&& infix Esquerda 8
de igualdade == infix Esquerda 9
de desigualdade != infix Esquerda 9
menor ou igual a <= infix Esquerda 10
menos de < infix Esquerda 11
maior que ou igual a >= infix Esquerda 11
maior que > infix Esquerda 11
de turno para a direita >>> infix Esquerda 12
de turno esquerdo <<< infix Esquerda 12
adição ou de concatenação + infix Esquerda 13
de subtração - infix Esquerda 13
de multiplicação * infix Esquerda 14
divisão / infix Esquerda 14
módulo % infix Esquerda 14
de exponencialização ^ infix Certo 15
NOT bit a bit ~~~ prefixo Certo 16
lógico NÃO not prefixo Certo 16
negativo - prefixo Certo 16

As expressões de cópia e atualização necessariamente precisam ter a menor precedência para garantir um comportamento consistente da instrução de avaliação e reatribução correspondente. Considerações semelhantes são consideradas para o operador de intervalo para garantir um comportamento consistente do expressão contextual correspondente.

Modificadores e combinadores

Os modificadores podem ser vistos como operadores especiais que podem ser aplicados somente a determinadas expressões. Eles podem receber uma precedência artificial para capturar seu comportamento.

Para obter mais informações, consulte Expressions.

Essa precedência artificial é listada na tabela a seguir, juntamente com a forma como a precedência de operadores e modificadores se relaciona com a associação de combinadores de acesso de itens ([,] e :: respectivamente) e combinadores de chamadas ((, )).

Descrição Sintaxe Operador Capacidade de associação Precedência
do combinador de chamadas ( ) n/a Esquerda 17
functor adjacente Adjoint prefixo Certo 18
de functor controlado Controlled prefixo Certo 18
desembrulhar de aplicativo ! Postfix Esquerda 19
acesso ao item nomeado . n/a Esquerda 20
de acesso de item do Array [ ] n/a Esquerda 20
função lambda -> n/a Certo 21
Operação lambda => n/a Certo 21

Para ilustrar as implicações das precedências atribuídas, suponha que você tenha uma operação unitária DoNothing (conforme definido em declarações de especialização ), um GetStatePrep que retorna uma operação unitária e uma matriz algorithms que contém itens do tipo Algorithm definidos da seguinte maneira

    struct Algorithm {
        Register : Qubit[],
        Initialize : Transformation,
        Apply : Transformation,
    } 

As seguintes expressões, então, são todas válidas:

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

Examinando as precedências definidas na tabela acima, você pode ver que os parênteses em torno de (Transformation(GetStatePrep())) são necessários para que o operador de unwrap subsequente seja aplicado ao valor Transformation em vez da operação retornada. No entanto, parênteses não são necessários no GetStatePrep()(arg); as funções são aplicadas da esquerda para a direita, portanto, essa expressão é equivalente a (GetStatePrep())(arg). Os aplicativos functor também não exigem parênteses ao seu redor para invocar a especialização correspondente, nem expressões de acesso de itens nomeados ou matriz. Portanto, a expressão arr2D[i][j] é perfeitamente válida, assim como algorithms[0]::Register![i].