你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
闭包是从封闭环境中捕获变量的可调用项。 可以创建函数和作关闭。 作关闭可以在函数内创建,但只能在作中应用。
Q# 有两种机制用于创建关闭:lambda 表达式和部分应用程序。
Lambda 表达式
lambda 表达式创建匿名函数或作。
基本语法是用于绑定参数的符号元组、函数的箭头(-> 和作的 =>),以及应用时要计算的表达式。
// Function that captures 'x':
y -> x + y
// Operation that captures 'qubit':
deg => Rx(deg * PI() / 180.0, qubit)
// Function that captures nothing:
(x, y) -> x + y
参数
参数使用与 变量声明语句左侧相同的符号元组绑定。 参数元组的类型是隐式的。 不支持类型批注;如果类型推理失败,可能需要创建顶级可调用声明并改用部分应用程序。
可变捕获变量
无法捕获可变变量。 如果只需在创建 lambda 表达式时捕获可变变量的值,则可以创建不可变副本:
// ERROR: 'variable' cannot be captured.
mutable variable = 1;
let f = () -> variable;
// OK.
let value = variable;
let g = () -> value;
特征
匿名作的特征是根据 lambda 的应用程序推断的。 如果 lambda 与 functor 应用程序一起使用,或在需要特征的上下文中,则推断 lambda 具有该特征。 例如:
operation NoOp(q : Qubit) : Unit is Adj {}
operation Main() : Unit {
use q = Qubit();
let foo = () => NoOp(q);
foo(); // Has type Unit => Unit with no characteristics
let bar = () => NoOp(q);
Adjoint bar(); // Has type Unit => Unit is Adj
}
如果需要与推断的运算 lambda 不同的特征,则需要改为创建顶级作声明。
部分应用程序
部分应用程序是一种方便的速记,用于应用可调用对象的一些参数,但并非全部。
语法与调用表达式相同,但未应用的参数将替换为 _。
从概念上讲,部分应用程序等效于一个 lambda 表达式,该表达式捕获已应用的参数,并将未应用的参数用作参数。
例如,鉴于 f 是一个函数,o 是一个作,并且捕获的变量 x 是不可变的:
| 部分应用程序 | Lambda 表达式 |
|---|---|
f(x, _) |
a -> f(x, a) |
o(x, _) |
a => o(x, a) |
f(_, (1, _)) |
(a, b) -> f(a, (1, b))[^1] |
f((_, _, x), (1, _)) |
((a, b), c) -> f((a, b, x), (1, c)) |
可变捕获变量
与 lambda 表达式不同,部分应用程序可以自动捕获可变变量值的副本:
mutable variable = 1;
let f = Foo(variable, _);
这等效于以下 lambda 表达式:
mutable variable = 1;
let value = variable;
let f = x -> Foo(value, x);
[^1]:参数元组严格写入 (a, (b)),但 (b) 等效于 b。