Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Wyrażenia kontekstowe to wyrażenia, które są prawidłowe tylko w niektórych kontekstach, takich jak użycie nazw elementów w wyrażeniach kopiowania i aktualizacji bez konieczności ich kwalifikowania.
Wyrażenia można pominąć, gdy można je wywnioskować i automatycznie wstawić przez kompilator, na przykład instrukcje evaluate-and-reassign.
Zakresy otwarte to kolejny przykład, który ma zastosowanie zarówno do wyrażeń kontekstowych, jak i pominiętych. Są one prawidłowe tylko w określonym kontekście, a kompilator tłumaczy je na normalne wyrażenia Range podczas kompilacji, wnioskowając odpowiednie granice.
Wartość typu Range generuje sekwencję liczb całkowitych określoną przez wartość początkową, wartość kroku (opcjonalnie) i wartość końcową. Na przykład wyrażenie literału Range1..3 generuje sekwencję 1,2,3. Podobnie wyrażenie 3..-1..1 generuje sekwencję 3,2,1. Za pomocą zakresów można również utworzyć nową tablicę na podstawie istniejącej, na przykład fragmentując:
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]
Nie można zdefiniować nieskończonego zakresu w Q#; wartości początkowe i końcowe muszą być zawsze określone. Jedynym wyjątkiem jest użycie Range do wycinków tablicy. W takim przypadku kompilator może rozsądnie wywnioskować wartości początkowe lub końcowe zakresu.
W poprzednich przykładach fragmentowania tablicy uzasadnione jest założenie, że docelowy koniec zakresu powinien być indeksem ostatniego elementu w tablicy, jeśli rozmiar kroku jest dodatni. Jeśli rozmiar kroku jest ujemny, prawdopodobnie koniec zakresu powinien być indeksem pierwszego elementu w tablicy, 0. Odwrotność zawiera początek zakresu.
Podsumowując, jeśli pominięto wartość początkową zakresu, wnioskowana wartość początkowa
- jest zero, jeśli nie określono żadnego kroku lub określony krok jest dodatni.
- jest długością tablicy minus jeden, jeśli określony krok jest ujemny.
Jeśli pominięto wartość końcową zakresu, wnioskowana wartość końcowa
- jest długością tablicy minus jeden, jeśli nie określono żadnego kroku lub określony krok jest dodatni.
- wartość zero, jeśli określony krok jest ujemny.
Q# z tego względu umożliwia korzystanie z zakresów otwartych w wyrażeniach fragmentowania tablicy, na przykład:
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];
Ponieważ określenie, czy krok zakresu jest pozytywny, czy ujemny występuje w czasie wykonywania, kompilator wstawia odpowiednie wyrażenie, które jest oceniane w czasie wykonywania. W przypadku pominiętych wartości końcowych wstawione wyrażenie jest step < 0 ? 0 | Length(arr)-1, a dla pominiętych wartości początkowych jest step < 0 ? Length(arr)-1 | 0, gdzie step jest wyrażeniem podanym dla kroku zakresu lub 1, jeśli nie określono żadnego kroku.