你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
默认情况下,在全局范围内声明的可调用声明或 可调用方公开可见;也就是说,可以在同一项目和引用声明程序集的项目中的任何位置使用它们。 Access 修饰符 允许你仅将其可见性限制为当前程序集,以便以后无需中断依赖于特定库的代码即可更改实现详细信息。
Q# 支持两种类型的可调用对象:作和函数。 Operations 和 Functions 主题 详细说明了两者之间的区别。 Q# 还支持定义 模板;例如,特定可调用对象的类型参数化实现。 有关详细信息,请参阅 类型参数化。
注释
此类类型参数化实现不得使用依赖于类型参数的特定属性的任何语言构造;目前无法表达 Q#中的类型约束,或为特定类型参数定义专用实现。
可调用方和 functor
Q# 允许专用实现用于特定目的;例如,Q# 中的作可以隐式或显式定义对某些 functor的支持,并结合它,在将特定 functor 应用于该可调用函数时要调用的专用实现。
从某种意义上说,一个 functor 是一个工厂,它定义了一个新的可调用实现,该实现与应用了可调用的可调用对象有特定关系。 Functor 比传统的更高级别的函数更高级别,因为它们需要访问已应用到的可调用对象的实现详细信息。 从这个意义上说,它们类似于其他工厂,如模板。 它们也可以应用于类型化可调用方。
请考虑以下作,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# 允许单独声明对每个 functor 的支持。 但是,由于这两个 functor 通勤,因此定义对两者的支持的作还必须具有实现(通常隐式定义,即编译器生成的),当这两个 functor 应用于该作时。
没有可应用于函数的函数。 函数目前只有一个正文实现,没有进一步的专用化。 例如,声明
function Hello (name : String) : String {
$"Hello, {name}!"
}
等效于
function Hello (name : String) : String {
body ... {
$"Hello, {name}!"
}
}
此处,body 指定给定的实现适用于函数 Hello的默认正文,这意味着在调用之前未应用任何函数或其他工厂机制时调用实现。
body ... 中的三个点对应于编译器指令,指示函数声明中的参数项应复制并粘贴到此位置。
显式指示要复制和粘贴父可调用声明的参数的原因有两倍:一个是不需要重复参数声明,两个是确保需要其他参数的 functor(如 Controlled functor)可以一致的方式引入。
当正好有一个专用化定义默认正文的实现时,可能会省略表单 body ... { <implementation> } 的额外包装。
递归
Q# 可调用方可以直接或间接递归,并且可以按任意顺序声明;作或函数可以调用自身,也可以调用直接或间接调用调用方的另一个可调用方。
在量子硬件上运行时,堆栈空间可能会受到限制,超过堆栈空间限制的递归会导致运行时错误。