Kontextové a vynechané výrazy

Kontextové výrazy jsou výrazy, které jsou platné pouze v určitých kontextech, například použití názvů položek ve výrazech kopírování a aktualizace , aniž by je bylo nutné kvalifikovat.

Výrazy mohou být vynechány , pokud je kompilátor může odvodit a automaticky vložit, například v případě příkazů evaluate-a-reassign.

Další příklad, který se vztahuje na kontextové i vynechané výrazy, jsou otevřené oblasti. Jsou platné pouze v určitém kontextu a kompilátor je během kompilace překládá na normální Range výrazy tím, že odvodí vhodné hranice.

Hodnota typu Range generuje sekvenci celých čísel určenou počáteční hodnotou, hodnotou kroku (volitelné) a koncovou hodnotou. Literálový Range výraz 1..3 například vygeneruje sekvenci 1,2,3. Podobně výraz 3..-1..1 vygeneruje sekvenci 3,2,1. Oblasti můžete také použít k vytvoření nového pole z existujícího pole pomocí řezů, například:

    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]

V souboru nelze definovat nekonečnou oblast Q#. Počáteční a koncová hodnota musí být vždy zadána. Jedinou výjimkou je Range použití k průřezu pole. V takovém případě může kompilátor rozumně odvodit počáteční nebo koncové hodnoty rozsahu.

V předchozích příkladech dělení polí je vhodné, aby kompilátor předpokládal, že zamýšleným koncem rozsahu by měl být index poslední položky v poli, pokud je velikost kroku kladná. Pokud je velikost kroku záporná, pak by konec oblasti pravděpodobně měl být index první položky v poli 0, . Hodnota converse platí pro začátek rozsahu.

Abychom to shrnuli, pokud vynecháte počáteční hodnotu rozsahu, odvozená počáteční hodnota

  • je nula, pokud není zadaný žádný krok nebo je zadaný krok kladný.
  • je délka pole minus jedna, pokud je zadaný krok záporný.

Pokud vynecháte koncovou hodnotu rozsahu, odvozená koncová hodnota

  • je délka pole mínus jedna, pokud není zadán žádný krok nebo je zadaný krok kladný.
  • je nula, pokud je zadaný krok záporný.

Q# proto umožňuje použití otevřených rozsahů v rámci výrazů pro dělení polí, například:

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

Vzhledem k tomu, že určení, zda je krok rozsahu kladný nebo záporný, probíhá za běhu, kompilátor vloží vhodný výraz, který bude vyhodnocen za běhu. Pro vynechané koncové hodnoty je step < 0 ? 0 | Length(arr)-1vložený výraz a pro vynechané počáteční hodnoty je step < 0 ? Length(arr)-1 | 0to , kde step je výraz zadaný pro krok rozsahu nebo 1 pokud není zadaný žádný krok.