Sdílet prostřednictvím


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 copy-and-update, aniž by je bylo nutné kvalifikovat.

Výrazy je možné vynechat , když je lze odvodit a automaticky vložit kompilátorem, například v případě příkazů evaluate-and-reassign.

Otevřené oblasti jsou dalším příkladem, který se vztahuje na kontextové i vynechané výrazy. Jsou platné pouze v určitém kontextu a kompilátor je během kompilace překládá na normální Range výrazy odvozením vhodných hranic.

Hodnota typu Range generuje posloupnost celých čísel určených počáteční hodnotou, hodnotou kroku (volitelné) a koncovou hodnotou. Například Range literálový výraz 1..3 vygeneruje sekvenci 1,2,3. Podobně výraz 3..-1..1 vygeneruje sekvenci 3,2,1. Rozsahy můžete použít také 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]

Nelze definovat nekonečný rozsah v Q#; počáteční a koncové hodnoty musí být vždy zadány. Jedinou výjimkou je použití průřezu Range pole. V takovém případě může kompilátor přiměřeně odvodit počáteční nebo koncové hodnoty rozsahu.

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

Chcete-li shrnout, pokud vynecháte počáteční hodnotu rozsahu, odvozená počáteční hodnota

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

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

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

Q# proto umožňuje použití otevřených oblastí v rámci výrazů 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 pozitivní nebo negativní, dojde za běhu, kompilátor vloží vhodný výraz, který bude vyhodnocen za běhu. U vynechaných koncových hodnot je step < 0 ? 0 | Length(arr)-1vložený výraz a pro vynechané počáteční hodnoty je step < 0 ? Length(arr)-1 | 0, kde step je výraz zadaný pro krok rozsahu nebo 1 pokud není zadán žádný krok.