Udostępnij za pośrednictwem


Wyrażenia kontekstowe i pominięte

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 w przypadku instrukcji 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 wyrażenia normalne 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 Range wyrażenie 1..3 literału 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 elem Q#. Zawsze należy określić wartości początkowe i końcowe. Jedynym wyjątkiem jest użycie obiektu Range w celu wycinek tablicy. W takim przypadku wartości początkowe lub końcowe zakresu można rozsądnie wywnioskować przez kompilator.

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, zakres prawdopodobnie 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# w związku z tym umożliwia użycie 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 negatywny występuje w czasie wykonywania, kompilator wstawia odpowiednie wyrażenie, które będzie oceniane w czasie wykonywania. W przypadku pominiętych wartości końcowych wstawione wyrażenie to step < 0 ? 0 | Length(arr)-1, a dla pominiętych wartości początkowych to step < 0 ? Length(arr)-1 | 0, gdzie step jest to wyrażenie podane dla kroku zakresu lub 1 jeśli nie określono żadnego kroku.