Compartir a través de


Expresiones contextuales y omitidas

Las expresiones contextuales son expresiones que solo son válidas en determinados contextos, como el uso de nombres de elementos en las expresiones de copia y actualización sin tener que calificarlos.

Además, las expresiones se pueden omitir cuando el compilador las puede inferir e insertar automáticamente, por ejemplo, en el caso de las instrucciones de evaluación y reasignación.

Los intervalos abiertos son otro ejemplo que se aplica a las expresiones contextuales y omitidas. Son válidos solo dentro de un contexto determinado y el compilador los traduce en expresiones normales Range durante la compilación mediante la inferencia de límites adecuados.

Un valor de tipo Range genera una secuencia de números enteros, especificada por un valor de inicio, un valor de paso (opcional) y un valor final. Por ejemplo, la expresión Range literal con el valor 1..3 genera la secuencia 1, 2, 3. Del mismo modo, la expresión 3..-1..1 genera la secuencia 3, 2, 1. También puede usar intervalos para crear una nueva matriz a partir de una existente mediante segmentación, por ejemplo:

    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]

No se puede definir un intervalo infinito en Q#; siempre se deben especificar los valores inicial y final. La única excepción ocurre cuando se usa Range para segmentar una matriz. En ese caso, el compilador puede inferir razonablemente el valor inicial o final del intervalo.

En los ejemplos anteriores de segmentación de una matriz, es razonable que el compilador suponga que el final pretendido del intervalo debe ser el índice del último elemento de la matriz, si el tamaño del paso es positivo. Si el tamaño del paso es negativo, el final del intervalo probablemente debe ser el índice del primer elemento de la matriz, 0. Lo contrario se mantiene para el inicio del intervalo.

En resumen, si se omite el valor inicial del intervalo, el valor inicial inferido

  • es cero si no se especifica ningún paso o si el paso especificado es positivo.
  • es la longitud de la matriz menos uno si el paso especificado es negativo.

Si se omite el valor final del intervalo, el valor final inferido

  • es la longitud de la matriz menos uno si no se especifica ningún paso o si el paso especificado es positivo.
  • es cero si el paso especificado es negativo.

Por lo tanto, Q# permite el uso de intervalos abiertos en las expresiones de segmentación de matrices, por ejemplo:

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

Dado que determinar si el paso del intervalo es positivo o negativo ocurre en tiempo de ejecución, el compilador inserta una expresión adecuada que se evaluará en tiempo de ejecución. Para los valores finales omitidos, la expresión insertada es step < 0 ? 0 | Length(arr)-1 y para los valores iniciales omitidos, es step < 0 ? Length(arr)-1 | 0, donde step es la expresión especificada para el paso de intervalo, o 1 si no se especifica ningún paso.