可呼叫宣告或 可呼叫者,預設會公開顯示於全域範圍;也就是說,它們可以用於相同項目和參考宣告元件之專案中的任何位置。 Access 修飾詞 可讓您只將其可見性限制為目前的元件,以便稍後可以變更實作詳細數據,而不需要中斷依賴特定連結庫的程式代碼。
Q# 支援兩種可呼叫專案:作業和函式。 Operations 和 Functions 主題 詳細說明這兩者之間的差異。 Q# 也支援定義 範本;例如,特定可呼叫的型別參數化實作。 如需詳細資訊,請參閱 Type 參數化。
備註
這類類型參數化實作不得使用依賴類型自變數特定屬性的任何語言建構;目前無法表達 Q#中的型別條件約束,或定義特定型別自變數的特製化實作。
可呼叫專案和函式
Q# 允許特定用途的特製化實作;例如,Q# 中的作業可以隱含或明確定義特定 函式的支援,以及將特定函式套用至該可呼叫函式時要叫用的特殊實作。
從某種意義上說,函式是一個處理站,定義新的可呼叫實作,該實作與所套用的可呼叫者有特定關聯。 運算函式比傳統的較高層級函式更進階,因為它們需要存取已套用之可呼叫的實作詳細數據。 從這個意義上說,它們與其他工廠類似,例如範本。 它們也可以套用至類型參數化可呼叫者。
請考慮下列作業,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]));
}
}
}
此作業會採用 類型為 Qubit[] 的自變數,並傳回類型為 Unit的值。 宣告 ApplyQFT 中的註釋 is Adj + Ctl 表示作業同時支援 Adjoint 和 Controlled 函式。 (如需詳細資訊,請參閱 作業特性)。 表達式 Adjoint ApplyQFT 存取實作 ApplyQFT相鄰的特製化,Controlled ApplyQFT 存取實作受控制版本的特製化 ApplyQFT。
除了原始作業的自變數之外,作業的受控制版本也會採用控制量子位數組,並在所有控制量子位都處於 |1⟩ 狀態的條件上套用原始作業。
理論上,可以定義相鄰版本的作業也應該有受控版本,反之亦然。 不過,在實務上,可能很難針對其中一個或其他專案開發實作,特別是針對重複到成功模式之後的概率實作。 因此,Q# 可讓您個別宣告每個函式的支援。 不過,由於這兩個函式通勤,定義兩者支援的作業也必須在兩個函式套用至作業時進行實作(通常隱含定義,表示編譯程式產生)。
沒有可套用至函式的函式。 函式目前只有一個主體實作,而且沒有進一步的特製化。 例如,宣告
function Hello (name : String) : String {
$"Hello, {name}!"
}
相當於
function Hello (name : String) : String {
body ... {
$"Hello, {name}!"
}
}
在這裡,body 指定指定的實作會套用至函式的預設主體 Hello,這表示在調用之前未套用任何函式或其他處理站機制時,會叫用實作。
body ... 中的三個點會對應至編譯程式指示詞,指出函式宣告中的自變數項目應該複製並貼到這個位置。
明確指出要複製和貼上父可呼叫宣告的自變數的背後原因有兩倍:一個是不需要重複自變數宣告,二是確保需要其他自變數的函式,例如 Controlled 運算函式,可以一致的方式引入。
當只有一個特製化定義預設主體的實作時,可能會省略窗體的額外包裝 body ... { <implementation> }。
遞迴
Q# 可呼叫者可以是直接或間接遞歸的,而且可以依任何順序宣告;作業或函式可以自行呼叫,或呼叫另一個直接或間接呼叫呼叫端的可呼叫者。
在量子硬體上執行時,堆疊空間可能會受到限制,而超過該堆疊空間限制的遞歸會導致運行時錯誤。