Meghívható deklarációk
A globális hatókörben deklarált hívható deklarációk vagy hívhatóak alapértelmezés szerint nyilvánosan láthatók; vagyis bárhol felhasználhatók ugyanabban a projektben és egy olyan projektben, amely a deklarált szerelvényre hivatkozik. A hozzáférési módosítók lehetővé teszik, hogy csak az aktuális szerelvényre korlátozzák a láthatóságukat, így az implementáció részletei később módosíthatók anélkül, hogy egy adott kódtárra támaszkodó kódtöredék lenne.
Q# kétféle hívható típust támogat: műveleteket és függvényeket. Az Operations and Functions (Műveletek és függvények ) témakör a kettő közötti különbségtételt ismerteti. Q# emellett támogatja a sablonok meghatározását is; például egy adott hívható típusparaméteres implementációi. További információ: Típusparaméterezések.
Megjegyzés
Az ilyen típusparametrizált implementációk nem használhatnak olyan nyelvi szerkezeteket, amelyek a típusargumentumok adott tulajdonságaira támaszkodnak; jelenleg nem lehet típuskényszereket kifejezni a rendszerben Q#, és nem lehet speciális implementációkat definiálni az adott típusargumentumokhoz.
Hívhatók és funktorok
Q# speciális megvalósításokat tesz lehetővé meghatározott célokra; például a benne lévő Q# műveletek implicit módon vagy explicit módon definiálhatják bizonyos funktorok támogatását, valamint azokat a speciális implementációkat, amelyeket meghívhat, amikor egy adott funktort alkalmaz a hívhatóra.
A funktor bizonyos értelemben olyan gyár, amely egy új hívható implementációt határoz meg, amely konkrét kapcsolatban áll azzal a hívhatóval, amelyre alkalmazták. A funktorok több, mint a hagyományos magasabb szintű függvények, mivel hozzáférést igényelnek a meghívható implementáció részleteihez, amelyekre alkalmazták őket. Ebben az értelemben hasonlóak más gyárakhoz, például sablonokhoz. Típusparaméteres hívhatókra is alkalmazhatók.
Fontolja meg a következő műveletet: ApplyQFT
operation ApplyQFT(qs : Qubit[]) : Unit is Adj + Ctl {
let length = Length(qs);
Fact(length >= 1, "ApplyQFT: Length(qs) must be at least 1.");
for i in length - 1..-1..0 {
H(qs[i]);
for j in 0..i - 1 {
Controlled R1Frac([qs[i]], (1, j + 1, qs[i - j - 1]));
}
}
}
Ez a művelet egy típus Qubit[]
argumentumot vesz fel, és egy típusértéket Unit
ad vissza. A deklarációban is Adj + Ctl
ApplyQFT
lévő széljegyzet azt jelzi, hogy a művelet a és a Adjoint
Controlled
funktort is támogatja. (További információ: Műveleti jellemzők). A kifejezés Adjoint ApplyQFT
hozzáfér a ( ) melléknevét ApplyQFT
implementáló specializációhoz, és Controlled ApplyQFT
hozzáfér a szabályozott verzióját implementáló specializációhoz ApplyQFT
.
Az eredeti művelet argumentumán kívül a művelet szabályozott verziója vezérlő qubitek tömbjét veszi igénybe, és az eredeti műveletet azzal a feltétellel alkalmazza, hogy az összes vezérlő qubit |1⟩ állapotban van.
Elméletileg egy olyan műveletnek, amelynek mellékverziója meghatározható, szintén szabályozott verzióval kell rendelkeznie, és fordítva. A gyakorlatban azonban nehéz lehet implementációt létrehozni az egyik vagy a másik számára, különösen a valószínűségi implementációk esetében, a sikeres ismétlődésig tartó mintát követve. Ezért lehetővé teszi az Q# egyes funktorok támogatásának egyenkénti deklarálásához. Mivel azonban a két funktor ingázik, a mindkettő támogatását meghatározó műveletnek rendelkeznie kell egy implementációval is (általában implicit módon, azaz fordító által generált módon), amikor mindkét funktort alkalmazza a műveletre.
Nincsenek funktorok, amelyek alkalmazhatók a függvényekre. A függvények jelenleg pontosan egy törzsmegvalósítással rendelkeznek, és nincsenek további specializációk. Például a deklaráció
function Hello (name : String) : String {
$"Hello, {name}!"
}
egyenértékű a
function Hello (name : String) : String {
body ... {
$"Hello, {name}!"
}
}
Itt azt adja meg, hogy az adott implementáció a függvény Hello
alapértelmezett törzsére vonatkozik, ami azt jelenti, body
hogy az implementáció akkor lesz meghívva, ha a meghívás előtt nem alkalmaztak funktorokat vagy más gyári mechanizmusokat. A három pont body ...
egy fordítóirányelvnek felel meg, amely azt jelzi, hogy a függvény deklarációjában szereplő argumentumelemeket erre a helyre kell másolni és beilleszteni.
A szülő hívható deklaráció argumentumainak másolásának és beillesztésének indokai kettősek: az egyik, az argumentum deklarációjának megismétlése szükségtelen, a második pedig biztosítja, hogy a további argumentumokat igénylő funktorok, például a Controlled
funktor, konzisztens módon is bevezethetők legyenek.
Ha pontosan egy specializáció határozza meg az alapértelmezett törzs implementációját, az űrlap body ... { <implementation> }
további burkolása kihagyható.
Rekurzió
Q# a hívhatóak lehetnek közvetlenül vagy közvetve rekurzívak, és bármilyen sorrendben deklarálhatók; egy művelet vagy függvény meghívhatja magát, vagy meghívhat egy másik hívhatót, amely közvetlenül vagy közvetve meghívja a hívót.
Kvantumhardveren való futtatáskor előfordulhat, hogy a veremterület korlátozott, és az ezt a veremterületkorlátot túllépő rekurzió futásidejű hibát eredményez.
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: