Déclarations et réaffectations de variables
Les valeurs peuvent être liées aux symboles à l’aide des instructions let
et mutable
.
Ces types de liaisons offrent un moyen pratique d’accéder à une valeur via le handle défini.
Malgré la terminologie trompeuse empruntée à d’autres langues, les handles déclarés sur une étendue locale et contenant des valeurs sont appelés variables.
Cela peut être trompeur, car let
instructions définissent handles à affectation unique, qui sont des handles qui restent liés à la même valeur pendant la durée de leur validité. Les variables qui peuvent être re-liées à différentes valeurs à différents points du code doivent être déclarées explicitement, et sont spécifiées à l’aide de l’instruction mutable
.
let var1 = 3;
mutable var2 = 3;
var2 = var2 + 1;
Dans cet exemple, l’instruction let
déclare une variable nommée var1
qui ne peut pas être réaffectée et contient toujours la valeur 3
. L’instruction mutable
définit une variable var2
liée temporairement à la valeur 3
, mais peut être réaffectée à une autre valeur ultérieurement à l’aide d’une expression d’affectation, comme indiqué dans la dernière ligne. Vous pouvez exprimer la même instruction avec la version plus courte var2 += 1;
, comme c’est le cas dans d’autres langues. Pour plus d’informations, consultez Évaluer et réaffecter des instructions.
Pour résumer :
-
let
est utilisé pour créer une liaison immuable. -
mutable
est utilisé pour créer une liaison mutable. -
=
sanslet
est utilisé pour modifier la valeur d’une liaison mutable.
Pour les trois instructions, le côté gauche se compose d’un symbole ou d’un tuple de symboles. Si le côté droit de la liaison est un tuple, ce tuple peut être entièrement ou partiellement déconstructé lors de l’affectation. La seule exigence de déconstruction est que la forme du tuple sur le côté droit correspond à la forme du tuple symbole sur le côté gauche. Le tuple de symbole peut contenir des tuples imbriqués ou des symboles omis, ou les deux, indiqués par un trait de soulignement. Par exemple:
let (a, (_, b)) = (1, (2, 3)); // a is bound to 1, b is bound to 3
mutable (x, y) = ((1, 2), [3, 4]); // x is bound to (1, 2), y is bound to [3, 4]
(x, _, y) = ((5, 6), 7, [8]); // x is re-bound to (5,6), y is re-bound to [8]
Pour plus d’informations sur la déconstruction à l’aide de l’opérateur unwrap (!
), consultez Accès Élément pour les types de struct.
Toutes les affectations dans Q# obéissent aux mêmes règles de décostruction, notamment les allocations qubits et les affectations de variables de boucle.
Pour les deux types de liaisons, les types des variables sont déduits du côté droit de la liaison. Le type d’une variable reste toujours le même et une expression d’affectation ne peut pas la modifier.
Les variables locales peuvent être déclarées comme mutables ou immuables. Il existe certaines exceptions, telles que les variables de boucle dans for
boucles, où le comportement est prédéfini et ne peut pas être spécifié.
Les arguments de fonction et d’opération sont toujours immuablement liés. En combinaison avec l’absence de types de référence, comme indiqué dans la rubrique immuabilité, cela signifie qu’une fonction ou une opération appelée ne peut jamais modifier les valeurs côté appelant.
Étant donné que les états de Qubit
valeurs ne sont pas définis ou observables à partir de Q#, cela n’empêche pas l’accumulation d’effets secondaires quantiques, qui sont observables uniquement par le biais de mesures. Pour plus d’informations, consultez types de données Quantum.
Indépendamment de la façon dont une valeur est liée, les valeurs elles-mêmes sont immuables. En particulier, cela est vrai pour les tableaux et les éléments de tableau. Contrairement aux langages classiques populaires où les tableaux sont souvent des types de référence, les tableaux de Q# , comme tous les types, sont des types valeur et toujours immuables ; autrement dit, vous ne pouvez pas les modifier après l’initialisation. La modification des valeurs accessibles par les variables de type tableau nécessite donc de construire explicitement un nouveau tableau et de le réaffecter au même symbole. Pour plus d’informations, consultez d’immuabilité et copier et mettre à jour des expressions.
Instructions Evaluate-and-reassign
Les instructions du formulaire intValue += 1;
sont courantes dans de nombreuses autres langues. Ici, intValue
doit être une variable de type Int
de type mutable.
Ces instructions fournissent un moyen pratique de concaténation si le côté droit consiste à appliquer un opérateur binaire et que le résultat est rebondir à l’argument gauche de l’opérateur.
Par exemple, ce segment de code
mutable counter = 0;
for i in 1 .. 2 .. 10 {
counter += 1;
// ...
}
incrémente la valeur du compteur counter
dans chaque itération de la boucle for
et équivaut à
mutable counter = 0;
for i in 1 .. 2 .. 10 {
counter = counter + 1;
// ...
}
Des instructions similaires existent pour un large éventail d’opérateurs . Ces expressions d’évaluation et de réaffectation existent pour tous les opérateurs où le type de la sous-expression la plus à gauche correspond au type d’expression. Plus précisément, ils sont disponibles pour les opérateurs logiques et binaires binaires, notamment le décalage droit et gauche, les expressions arithmétiques, y compris l’exponentiation et le module, et les concaténations, ainsi que les expressions de copie et de mise à jour .
L’exemple de fonction suivant calcule la somme d’un tableau de nombres Complex
:
function ComplexSum(values : Complex[]) : Complex {
mutable res = Complex(0., 0.);
for complex in values {
res = new Complex { Re = res.Re + complex.Re, Im = res.Im + complex.Im };
}
return res;
}
De même, la fonction suivante multiplie chaque élément d’un tableau avec le facteur donné :
function Multiplied(factor : Double, array : Double[]) : Double[] {
mutable res = new Double[Length(array)];
for i in IndexRange(res) {
res w/= i <- factor * array[i];
}
return res;
}
Pour plus d’informations, consultez expressions contextuelles, qui contient d’autres exemples où les expressions peuvent être omises dans un contexte spécifique lorsqu’une expression appropriée peut être déduite par le compilateur.