Variabeledeclaraties en hertoewijzingen
Waarden kunnen worden gebonden aan symbolen met behulp van de instructies let
en mutable
.
Dit soort bindingen biedt een handige manier om toegang te krijgen tot een waarde via de gedefinieerde ingang.
Ondanks de misleidende terminologie die uit andere talen is geleend, worden handles die zijn gedeclareerd op een lokaal bereik en waarden genoemd variabelen.
Dit kan misleidend zijn omdat let
instructies ingangen met één toewijzingdefiniëren. Dit zijn ingangen die afhankelijk blijven van dezelfde waarde voor de duur van de geldigheid. Variabelen die opnieuw kunnen worden gebonden aan verschillende waarden op verschillende punten in de code, moeten expliciet als zodanig worden gedeclareerd en worden opgegeven met behulp van de instructie mutable
.
let var1 = 3;
mutable var2 = 3;
var2 = var2 + 1;
In dit voorbeeld declareert de let
-instructie een variabele met de naam var1
die niet opnieuw kan worden toegewezen en altijd de waarde 3
bevat. De instructie mutable
definieert een variabele var2
die tijdelijk is gebonden aan de waarde 3
, maar later opnieuw kan worden toegewezen aan een andere waarde met behulp van een toewijzingsexpressie, zoals wordt weergegeven in de laatste regel. U kunt dezelfde instructie uitdrukken met de kortere versie var2 += 1;
, zoals gebruikelijk in andere talen. Zie Instructies evalueren en opnieuw toewijzenvoor meer informatie.
Samenvatten:
-
let
wordt gebruikt om een onveranderbare binding te maken. -
mutable
wordt gebruikt om een onveranderbare binding te maken. -
=
zonderlet
wordt gebruikt om de waarde van een onveranderbare binding te wijzigen.
Voor alle drie de instructies bestaat de linkerkant uit een symbool of een symbool tuple. Als de rechterkant van de binding een tuple is, kan die tuple volledig of gedeeltelijk worden gedeconstrueerd bij de toewijzing. De enige vereiste voor deconstructie is dat de vorm van de tuple aan de rechterkant overeenkomt met de vorm van de symbool tuple aan de linkerkant. De symbool-tuple kan geneste tuples of weggelaten symbolen bevatten, of beide, aangegeven door een onderstrepingsteken. Bijvoorbeeld:
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]
Zie Itemtoegang voor structtypenvoor meer informatie over de destructie met behulp van de operator unwrap (!
).
Alle toewijzingen in Q# voldoen aan dezelfde destructieregels, waaronder bijvoorbeeld qubittoewijzingen en lusvariabeletoewijzingen.
Voor beide soorten bindingen worden de typen variabelen afgeleid van de rechterkant van de binding. Het type variabele blijft altijd hetzelfde en een toewijzingsexpressie kan deze niet wijzigen.
Lokale variabelen kunnen worden gedeclareerd als veranderlijk of onveranderbaar. Er zijn enkele uitzonderingen, zoals lusvariabelen in for
-lussen, waarbij het gedrag vooraf is gedefinieerd en niet kan worden opgegeven.
Functie- en bewerkingsargumenten zijn altijd onveranderlijk gebonden. In combinatie met het ontbreken van verwijzingstypen, zoals besproken in het onveranderbaarheid onderwerp, betekent dit dat een aangeroepen functie of bewerking nooit waarden aan de aanroeperzijde kan wijzigen.
Aangezien de toestanden van Qubit
waarden niet zijn gedefinieerd of waarneembaar zijn vanuit Q#, sluit dit de accumulatie van kwantumeffecten, die alleen via metingen kunnen worden waargenomen, niet uit. Zie Quantum-gegevenstypenvoor meer informatie.
Onafhankelijk van hoe een waarde wordt gebonden, zijn de waarden zelf onveranderbaar. Dit geldt met name voor matrices en matrixitems. In tegenstelling tot populaire klassieke talen waar matrices vaak verwijzingstypen zijn, zijn matrices in Q# - zoals alle typen - waardetypen en altijd onveranderbaar; Dat wil gezegd, u kunt ze niet wijzigen na initialisatie. Als u de waarden wijzigt die worden gebruikt door variabelen van het matrixtype, moet u dus expliciet een nieuwe matrix maken en deze opnieuw toewijzen aan hetzelfde symbool. Zie onveranderbaarheid en expressies kopiëren en bijwerkenvoor meer informatie.
Instructies evalueren en opnieuw toewijzen
Instructies van het formulier intValue += 1;
zijn gebruikelijk in veel andere talen. Hier moet intValue
een mutabele variabele van het type Int
zijn.
Dergelijke instructies bieden een handige manier om samen te voegen als de rechterkant bestaat uit het toepassen van een binaire operator en het resultaat wordt teruggegaan naar het linkerargument van de operator.
Bijvoorbeeld dit codesegment
mutable counter = 0;
for i in 1 .. 2 .. 10 {
counter += 1;
// ...
}
de waarde van de teller counter
in elke iteratie van de for
lus wordt verhoogd en gelijk is aan
mutable counter = 0;
for i in 1 .. 2 .. 10 {
counter = counter + 1;
// ...
}
Er bestaan vergelijkbare instructies voor een breed scala aan operators. Dergelijke expressies voor evalueren en opnieuw toewijzen bestaan voor alle operators waarbij het type van de meest linkse subexpressie overeenkomt met het expressietype. Meer precies, ze zijn beschikbaar voor binaire logische en bitgewijze operators, waaronder rechts- en links shift, rekenkundige expressies, waaronder exponentiatie en modulus, en samenvoegingen, evenals copy-and-update-expressies.
In het volgende functievoorbeeld wordt de som berekend van een matrix van Complex
getallen:
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;
}
Op dezelfde manier vermenigvuldigt de volgende functie elk item in een matrix met de opgegeven factor:
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;
}
Zie voor meer informatie Contextuele expressies, die andere voorbeelden bevat waarin expressies kunnen worden weggelaten in een specifieke context wanneer een geschikte expressie kan worden afgeleid door de compiler.