Acesso ao item
Q# suporta o acesso a itens para itens de matriz e para itens em tipos definidos pelo utilizador. Em ambos os casos, o acesso é só de leitura; não é possível alterar o valor sem criar uma nova instância com uma expressão copy-and-update.
Acesso a itens de matriz e segmentação de matriz
Tendo em conta uma expressão de matriz e uma expressão do tipo Int
ou Range
, pode formar-se uma nova expressão com o operador de acesso de item de [
matriz que consiste em e ]
.
Se a expressão dentro dos parênteses retos for do tipo Int
, a nova expressão contém o item de matriz nesse índice.
Por exemplo, se arr
for do tipo Double[]
e contiver cinco ou mais itens, arr[4]
será uma expressão do tipo Double
.
Se a expressão dentro dos parênteses retos for do tipo Range
, a nova expressão contém uma matriz de todos os itens indexados pelo especificado Range
. Se o Range
estiver vazio, a matriz resultante estará vazia.
Por exemplo,
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]
Na última linha do exemplo, o valor de início e de fim do intervalo foi omitido por conveniência. Para obter mais informações, veja Expressões contextuais.
Se a expressão de matriz não for um identificador simples, tem de estar entre parênteses para extrair um item ou um setor.
Por exemplo, se arr1
e arr2
forem ambas matrizes de números inteiros, um item da concatenação será expresso como (arr1 + arr2)[13]
. Para obter mais informações, veja Precedência e associatividade.
Todas as matrizes no são baseadas em Q# zero, ou seja, o primeiro elemento de uma matriz arr
é sempre arr[0]
.
É emitida uma exceção no runtime se o índice ou um dos índices utilizados para a segmentação estiver fora dos limites da matriz, por exemplo, se for menor que zero ou maior ou igual ao comprimento da matriz.
Acesso a itens para tipos definidos pelo utilizador
(Para obter mais informações sobre como definir tipos personalizados que contenham um ou mais itens nomeados ou anónimos, consulte Declarações de tipo).
Os itens contidos podem ser acedidos através do respetivo nome ou por desconstrução, ilustrado pelas seguintes instruções que podem ser utilizadas como parte de uma operação ou implementação de função:
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
O operador de acesso a itens (::
) obtém itens nomeados, conforme ilustrado pelo exemplo seguinte:
newtype TwoStrings = (str1 : String, str2 : String);
operation LinkTwoStrings(str : TwoStrings) : String {
let s1 = str::str1;
let s2 = str::str2;
return s1 + s2;
}
Embora os itens nomeados possam ser acedidos pelo respetivo nome ou por desconstrução, os itens anónimos só podem ser acedidos por este último. Uma vez que a desconstrução depende de todos os itens contidos, a utilização de itens anónimos é desencorajada quando estes itens precisam de ser acedidos fora da unidade de compilação na qual o tipo é definido.
O acesso através da desconstrução utiliza o operador unwrap (!
). O operador unwrap devolve uma cadeia de identificação de todos os itens contidos, em que a forma da cadeia de identificação corresponde à definida na declaração e uma única cadeia de identificação de itens é equivalente ao próprio item (consulte esta secção).
Por exemplo, para um valor nested
do tipo Nested
que é definido da seguinte forma
newtype Nested = (Double, (ItemName : Int, String));
a expressão nested!
devolve um valor do tipo (Double, (Int, String))
.
O !
operador tem uma precedência mais baixa do que ambos os operadores de acesso a itens, mas uma precedência superior à de qualquer outro operador. Para obter uma lista completa de precedências, veja Precedência e associatividade.