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)-1
vlož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.