Compartilhar via


Expressões contextuais e omitidas

As expressões contextuais são válidas apenas em determinados contextos, como no uso de nomes de item em expressões de cópia e atualização sem necessidade de qualificação.

Além disso, as expressões podem ser omitidas quando podem ser inferidas e inseridas automaticamente pelo compilador, como é o caso nas instruções de avaliação e reatribuição.

Os intervalos abertos são outro exemplo que se aplicam a expressões contextuais e omitidas. Eles são válidos apenas dentro de um determinado contexto, e o compilador os traduz em expressões normais Range durante a compilação, inferindo limites adequados.

Um valor do tipo Range gera uma sequência de inteiros, especificada por um valor inicial, um valor de etapa (opcional) e um valor final. Por exemplo, a expressão 1..3 do literal Range gera a sequência 1,2,3. Da mesma forma, a expressão 3..-1..1 gera a sequência 3,2,1. Os intervalos também podem ser usados para criar uma matriz usando outra existente por divisão, por exemplo:

    let arr = [1,2,3,4];
    let slice1 = arr[1..2..4];  // contains [2,4] 
    let slice2 = arr[2..-1..0]; // contains [3,2,1]

Não é possível definir um intervalo infinito em Q#. Os valores de início e final sempre precisam ser especificados. A única exceção é quando você usa um Range para dividir uma matriz. Nesse caso, o valor inicial ou final do intervalo pode ser inferido corretamente pelo compilador.

Nos exemplos de divisão de matriz anteriores, é plausível que o compilador assuma que o final do intervalo pretendido seja o índice do último item na matriz quando o tamanho da etapa é positivo. Quando o tamanho da etapa é negativo, o final do intervalo provavelmente é o índice do primeiro item na matriz, 0. O inverso ocorre para o início do intervalo.

Para resumir, quando você omitir o valor inicial do intervalo, o valor inicial inferido

  • será zero se não for especificada nenhuma etapa ou se a etapa especificada for positiva.
  • será o comprimento da matriz menos um se a etapa especificada for negativa.

Quando você omitir o valor final do intervalo, o valor final inferido

  • será o comprimento da matriz menos um se não for especificada nenhuma etapa ou se a etapa especificada for positiva.
  • será zero se a etapa especificada for negativa.

Portanto, o Q# permite usar intervalos com final em aberto em expressões de divisão de matriz, por exemplo:

let arr = [1,2,3,4,5,6];
let slice1  = arr[3...];      // slice1 is [4,5,6];
let slice2  = arr[0..2...];   // slice2 is [1,3,5];
let slice3  = arr[...2];      // slice3 is [1,2,3];
let slice4  = arr[...2..3];   // slice4 is [1,3];
let slice5  = arr[...2...];   // slice5 is [1,3,5];
let slice7  = arr[4..-2...];  // slice7 is [5,3,1];
let slice8  = arr[...-1..3];  // slice8 is [6,5,4];
let slice9  = arr[...-1...];  // slice9 is [6,5,4,3,2,1];
let slice10 = arr[...];       // slice10 is [1,2,3,4,5,6];

Em tempo de execução, é determinado se a etapa de intervalo é positiva ou negativa, portanto, o compilador insere uma expressão adequada que será avaliada em tempo de execução. Para valores finais omitidos, a expressão inserida é step < 0 ? 0 | Length(arr)-1. Para valores iniciais omitidos, é step < 0 ? Length(arr)-1 | 0, em que step é a expressão fornecida para a etapa de intervalo ou 1 se nenhuma etapa é especificada.