Expressões contextuais e omitidas
Expressões contextuais são expressões válidas apenas em determinados contextos, como o uso de nomes de itens em expressões de cópia e atualização sem precisar qualificá-las.
As expressões podem ser omitidas quando podem ser inferidas e inseridas automaticamente pelo compilador, como instruções de avaliação e reatribução .
Intervalos abertos são outro exemplo que se aplica a expressões contextuais e omitidas. Elas são válidas somente em um determinado contexto e o compilador as converte em expressões de Range
normais 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 literal Range
1..3
gera a sequência 1,2,3. Da mesma forma, a expressão 3..-1..1
gera a sequência 3,2,1. Você também pode usar intervalos para criar uma nova matriz de uma existente cortando, 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]
Você não pode definir um intervalo infinito em Q#; os valores inicial e final sempre precisam ser especificados. A única exceção é quando você usa um Range
para fatiar uma matriz. Nesse caso, o compilador pode inferir razoavelmente os valores de início ou de término do intervalo.
Nos exemplos de fatiamento da matriz anterior, é razoável que o compilador assuma que a extremidade de intervalo pretendida deve ser o índice do último item na matriz se o tamanho da etapa for positivo. Se o tamanho da etapa for negativo, a extremidade do intervalo provavelmente deverá ser o índice do primeiro item na matriz, 0
. O inverso é válido para o início do intervalo.
Para resumir, se você omitir o valor inicial do intervalo, o valor inicial inferido
- será zero se nenhuma etapa for especificada ou a etapa especificada for positiva.
- é o comprimento da matriz menos um se a etapa especificada for negativa.
Se você omitir o valor final do intervalo, o valor final inferido
- é o comprimento da matriz menos uma se nenhuma etapa for especificada ou a etapa especificada for positiva.
- será zero se a etapa especificada for negativa.
Q#, portanto, permite o uso de intervalos abertos dentro de expressões de fatiamento 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];
Como a determinação de se a etapa de intervalo é positiva ou negativa ocorre em runtime, o compilador insere uma expressão adequada que é avaliada em runtime. Para valores finais omitidos, a expressão inserida é step < 0 ? 0 | Length(arr)-1
e, para valores de início omitidos, é step < 0 ? Length(arr)-1 | 0
, em que step
é a expressão fornecida para a etapa de intervalo ou 1
se nenhuma etapa for especificada.