Condividi tramite


Espressioni contestuali e omesse

Le espressioni contestuali sono espressioni valide solo in determinati contesti, ad esempio l'uso di nomi di elementi in espressioni di copia e aggiornamento senza doverli qualificare.

Le espressioni possono essere omesse quando possono essere dedotte e inserite automaticamente dal compilatore, ad esempio istruzioni evaluate-and-reassign.

Gli intervalli aperti sono un altro esempio che si applica alle espressioni contestuali e omesse. Sono validi solo all'interno di un determinato contesto e il compilatore li converte in espressioni di Range normali durante la compilazione dedurndo i limiti appropriati.

Un valore di tipo Range genera una sequenza di numeri interi, specificati da un valore iniziale, un valore di passaggio (facoltativo) e un valore finale. Ad esempio, l'espressione letterale Range1..3 genera la sequenza 1,2,3. Analogamente, l'espressione 3..-1..1 genera la sequenza 3,2,1. È anche possibile usare gli intervalli per creare una nuova matrice da una esistente sezionando, ad esempio:

    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]

Non è possibile definire un intervallo infinito in Q#; i valori iniziale e finale devono sempre essere specificati. L'unica eccezione è quando si usa un Range per sezionare una matrice. In tal caso, il compilatore può ragionevolmente dedurre i valori iniziale o finale dell'intervallo.

Negli esempi di sezionamento della matrice precedente, è ragionevole che il compilatore presupporre che la fine dell'intervallo previsto sia l'indice dell'ultimo elemento nella matrice se la dimensione del passaggio è positiva. Se la dimensione del passaggio è negativa, è probabile che l'intervallo finale sia l'indice del primo elemento nella matrice, 0. Il contrario tiene per l'inizio dell'intervallo.

Per riepilogare, se si omette il valore iniziale dell'intervallo, il valore iniziale dedotto

  • è zero se non viene specificato alcun passaggio o il passaggio specificato è positivo.
  • è la lunghezza della matrice meno una se il passaggio specificato è negativo.

Se si omette il valore finale dell'intervallo, il valore finale dedotto

  • è la lunghezza della matrice meno uno se non viene specificato alcun passaggio o il passaggio specificato è positivo.
  • è zero se il passaggio specificato è negativo.

Q# quindi consente l'uso di intervalli aperti all'interno di espressioni di sezionamento di matrici, ad esempio:

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];

Poiché la determinazione del passaggio dell'intervallo è positivo o negativo in fase di esecuzione, il compilatore inserisce un'espressione appropriata valutata in fase di esecuzione. Per i valori finali omessi, l'espressione inserita viene step < 0 ? 0 | Length(arr)-1e per i valori iniziali omessi viene step < 0 ? Length(arr)-1 | 0, dove step è l'espressione specificata per il passaggio dell'intervallo oppure 1 se non viene specificato alcun passaggio.