Partilhar via


Precedência e associatividade

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

Operadores

A tabela seguinte lista os operadores disponíveis no Q#, bem como a precedência e associatividade. Estão também listados modificadores e combinadores adicionais e vinculados mais apertados do que qualquer um destes operadores.

Description Syntax Operador Associatividade Precedência
operador copy-and-update w/ <- ternary esquerda 1
operador range .. infixo esquerda 2
operador condicional ? \| ternary right 3
lógico OU or infixo esquerda 4
lógico E and infixo esquerda 5
bit-a-bit OU \|\|\| infixo esquerda 6
bitwise XOR ^^^ infixo esquerda 7
bitwise AND &&& infixo esquerda 8
igualdade == infixo esquerda 9
desigualdade != infixo esquerda 9
menor que ou igual <= infixo esquerda 10
menor do que < infixo esquerda 11
maior do que ou igual >= infixo esquerda 11
maior do que > infixo esquerda 11
shift para a direita >>> infixo esquerda 12
shift esquerdo <<< infixo esquerda 12
adição ou concatenação + infixo esquerda 13
subtração - infixo esquerda 13
multiplicação * infixo esquerda 14
divisão / infixo esquerda 14
modulus % infixo esquerda 14
exponenciação ^ infixo right 15
bitwise NOT ~~~ prefixo right 16
lógico NÃO not prefixo right 16
negativo - prefixo right 16

As expressões copy-and-update precisam necessariamente de ter a precedência mais baixa para garantir um comportamento consistente da instrução de avaliação e reatribuição correspondente. Considerações semelhantes 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 só podem ser aplicados a determinadas expressões. Pode ser-lhes atribuída uma precedência artificial para capturar o seu comportamento.

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

Esta precedência artificial está listada na tabela seguinte, juntamente com a forma como a precedência dos operadores e modificadores se relaciona com a forma como os combinadores de acesso aos itens ([e::,] respetivamente) e os combinadores de chamadas ((, )) se vinculam.

Description Syntax Operador Associatividade Precedência
Combinador de chamadas ( ) n/a esquerda 17
Functor adjacente Adjoint prefixo right 18
Functor controlado Controlled prefixo right 18
Desembrulhar a aplicação ! postfixo esquerda 19
Acesso a itens nomeados :: n/a esquerda 20
Acesso a item de matriz [ ] n/a esquerda 20
Função lambda -> n/a right 21
Operação lambda => n/a right 21

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

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

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

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

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

Olhando para as precedências definidas na tabela acima, pode ver que os parênteses à volta (Transformation(GetStatePrep())) são necessários para que o operador de desembrulhar subsequente seja aplicado ao Transformation valor em vez da operação devolvida. No entanto, os parênteses não são necessários em GetStatePrep()(arg); as funções são aplicadas da esquerda para a direita, pelo que esta expressão é equivalente a (GetStatePrep())(arg). As aplicações de functor também não necessitam de parênteses à sua volta para invocar a especialização correspondente, nem expressões de acesso de matriz ou item nomeado. Assim, a expressão arr2D[i][j] é perfeitamente válida, tal como .algorithms[0]::Register![i]