Partilhar via


Precedência e associatividade

Precedência e associatividade definem a ordem em que os operadores são aplicados. Os operadores com maior precedência são vinculados aos seus argumentos (operandos) primeiro, enquanto os operadores com a mesma precedência se ligam na direção de sua associatividade. Por exemplo, a expressão 1+2*3 de acordo com a precedência para adição e multiplicação é equivalente a 1+(2*3), e 2^3^4 é igual a 2^(3^4) uma vez que a exponenciação é associativa à direita.

Operadores

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

Descrição Sintaxe Operador Associatividade Precedência
operador de cópia e atualização w/ <- ternário Esquerda 1
operador de gama .. Infix Esquerda 2
operador condicional ? \| ternário Certo 3
lógica OU or Infix Esquerda 4
lógica E and Infix Esquerda 5
bit a bit OU \|\|\| Infix Esquerda 6
XOR bit a bit ^^^ Infix Esquerda 7
bitwise E &&& Infix Esquerda 8
igualdade == Infix Esquerda 9
desigualdade != Infix Esquerda 9
inferior ou igual <= Infix Esquerda 10
menos de < Infix Esquerda 11
maior do que igual >= Infix Esquerda 11
maior do que > Infix Esquerda 11
de mudança para a direita >>> Infix Esquerda 12
turno à esquerda <<< Infix Esquerda 12
adição ou concatenação + Infix Esquerda 13
de subtração - Infix Esquerda 13
multiplicação * Infix Esquerda 14
divisão / Infix Esquerda 14
módulo % Infix Esquerda 14
de exponenciação ^ Infix Certo 15
bitwise NÃO ~~~ prefixo Certo 16
lógico NÃO not prefixo Certo 16
negativo - prefixo Certo 16

As expressões de copiar e atualizar precisam necessariamente ter a menor precedência para garantir um comportamento consistente da instrução correspondente avaliar e reatribuir. Considerações semelhantes valem para o operador de intervalo para garantir um comportamento consistente da expressão contextual correspondente.

Modificadores e combinadores

Os modificadores podem ser vistos como operadores especiais que podem ser aplicados apenas a determinadas expressões. Pode-lhes ser atribuída uma precedência artificial para capturar o seu comportamento.

Para obter mais informações, consulte Expressões.

Essa precedência artificial está listada na tabela a seguir, juntamente com a forma como a precedência dos operadores e modificadores se relaciona com a estreita ligação dos combinadores de acesso ao item ([,] e ::, respectivamente) e dos combinadores de chamada ((, )).

Descrição Sintaxe Operador Associatividade Precedência
Combinador de chamadas ( ) não aplicável Esquerda 17
Functor Adjoint Adjoint prefixo Certo 18
Functor controlado Controlled prefixo Certo 18
Aplicação Unwrap ! Postfix Esquerda 19
Acesso ao item nomeado . não aplicável Esquerda 20
de acesso a itens de matriz [ ] não aplicável Esquerda 20
Função lambda -> não aplicável Certo 21
Operação lambda => não aplicável 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 chamável que retorna uma operação unitária e uma matriz algorithms que contém itens do tipo Algorithm definida da seguinte forma

    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]

Observando as precedências definidas na tabela acima, você pode ver que os parênteses em torno (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, não são necessários parênteses em GetStatePrep()(arg); As funções são aplicadas da esquerda para a direita, de modo que esta expressão é equivalente a (GetStatePrep())(arg). Os aplicativos functor também não exigem parênteses em torno deles para invocar a especialização correspondente, nem expressões de acesso a array ou item nomeado. Assim, a expressão arr2D[i][j] é perfeitamente válida, assim como algorithms[0]::Register![i].