Compartir a través de


Acceso a elementos

Q# admite el acceso a elementos para elementos de matriz y elementos en tipos definidos por el usuario. En ambos casos, el acceso es de solo lectura; el valor no se puede cambiar sin crear una nueva instancia mediante una expresión de copia y actualización.

Acceso a elementos de matriz y segmentación de matrices

Dada una expresión de matriz y una expresión de tipo Int o Range, se puede formar una expresión nueva mediante el operador de acceso a elementos de matriz que consta de [ y ].

Si la expresión entre corchetes es de tipo Int, la nueva expresión contiene el elemento de matriz de ese índice. Por ejemplo, si arr es de tipo Double[] y contiene cinco o más elementos, arr[4] es una expresión de tipo Double.

Si la expresión entre corchetes es de tipo Range, la nueva expresión contiene una matriz de todos los elementos indexados por el elemento Range especificado. Si el elemento Range está vacío, la matriz resultante estará vacía. Por ejemplo,

let arr = [10, 11, 36, 49];
let ten = arr[0]; // contains the value 10
let odds = arr[1..2..4]; // contains the value [11, 49]
let reverse = arr[...-1...]; // contains the value [49, 36, 11, 10]

En la última línea del ejemplo, el valor inicial y final del intervalo se han omitido por comodidad. Para más información, consulte Expresiones contextuales.

Si la expresión de matriz no es un identificador simple, se debe incluir entre paréntesis para extraer un elemento o un segmento. Por ejemplo, si arr1 y arr2 son matrices de enteros, un elemento de la concatenación se expresaría como (arr1 + arr2)[13]. Para más información, consulte Precedencia y asociatividad.

Todas las matrices de Q# son de base cero, es decir, el primer elemento de una matriz arr siempre es arr[0]. Se produce una excepción en tiempo de ejecución si el índice o uno de los índices usados para la segmentación está fuera de los límites de la matriz, por ejemplo, si es menor que cero o mayor o igual que la longitud de la matriz.

Acceso a elementos para tipos definidos por el usuario

(Para más información sobre cómo definir tipos personalizados que contienen uno o varios elementos con nombre o anónimos, consulte Declaraciones de tipos).

Se puede acceder a los elementos contenidos a través de su nombre o deconstrucción, que se ilustran en las siguientes instrucciones que se pueden usar como parte de una implementación de operación o función:

    let complex = Complex(1., 0.); // create a value of type Complex
    let (re, _) = complex!;       // item access via deconstruction
    let im = complex::Imaginary;  // item access via name

El operador de acceso a elementos (::) recupera elementos con nombre, como se muestra en el ejemplo siguiente:

newtype TwoStrings = (str1 : String, str2 : String);

operation LinkTwoStrings(str : TwoStrings) : String {
    let s1 = str::str1;
    let s2 = str::str2;
    return s1 + s2;
}

Aunque se puede acceder a los elementos con nombre mediante su nombre o a través de la deconstrucción, solo la última opción puede acceder a los elementos anónimos. Puesto que la deconstrucción se basa en todos los elementos contenidos, el uso de elementos anónimos no es recomendable cuando es necesario tener acceso a estos elementos fuera de la unidad de compilación en la que se define el tipo.

El acceso a través de la deconstrucción hace uso del operador de desencapsulado (!). El operador unwrap devuelve una tupla de todos los elementos contenidos, donde la forma de la tupla coincide con la definida en la declaración y una tupla de un solo elemento es equivalente al propio elemento (consulte esta sección).

Por ejemplo, para un valor nested de tipo Nested definido como se indica a continuación,

newtype Nested = (Double, (ItemName : Int, String));

la expresión nested! devuelve un valor de tipo (Double, (Int, String)).

El operador ! tiene una precedencia menor que ambos operadores de acceso a elementos, pero mayor que cualquier otro operador. Para obtener una lista completa de las precedencias, consulte Precedencia y asociatividad.