局部变量
通过使用let
关键字,可以将Q#中的任何类型的值分配给变量,以便在操作或函数内重用。 例如:
let measurementOperator = [PauliX; PauliZ; PauliZ; PauliX; PauliI];
这将Pauli运算符的特定数组分配给称为measurementOperator
变量。
Tip
请注意,我们不需要明确指定新变量的类型,因为let
语句右侧的表达式是明确的,并且类型由编译器推断。
Q#中的变量是不可变的 ,这意味着一旦以这种方式定义变量,就不能再以任何方式进行更改。 这可以进行多种有益的优化,包括对应用操作的Adjoint
变体进行重新排序的变量的经典逻辑的优化。
如上所述使用let
绑定的变量对于特定范围是本地的,例如操作的主体或for
循环的内容。
可变性
作为使用let
创建变量的替代方法, mutable
关键字将创建一个特殊的可变变量,可在使用set
关键字初始创建后进行更改。 如果一个可变变量是一个数组类型,那么该数组的元素也可以被改变。 例如,这对于以编程方式创建数组非常有用:
function Squares(nSquares : Int) : Int[] {
mutable squares = new Int[nSquares];
for (idxSquare in 0..nSquares - 1) {
set squares[idxSequare] = idxSquare ^ 2;
}
return squares;
}
上面的例子也说明了Q#中可变性的另一个重要特性:绑定到可变局部变量的数组本身是可变的。 正如我们在讨论数组类型时会更详细地看到的那样,普通变量不是这样。 非正式地说,从不可变变量递减的集合是不可变的,而从可变变量递减的集合是可变的。
没有操作或函数调用Squares
可以观察到局部变量squares
被定义为可变的; 可变性是调用者不需要担心的实现细节。 这为隔离专门功能和操作中的可变性提供了一种重要方法。 特别是,即使使用可变变量的操作不能使用adjoint auto
,操作也可以调用使用可变性的函数。 由于这个原因,使可变性尽可能短而紧凑的函数和操作是一个很好的做法,所以量子程序的其余部分可以用普通的不可变变量来编写。
解构
除了分配单个变量之外, let
关键字还允许解开元组类型的内容。 据说这种形式的分配解构了该元组的元素。 例如,如果我们用一个元组对一个哈密尔顿算子进行建模,那么我们可以使用解构来访问我们需要在该项下模拟的不同数据:
// Represents H = 3.1 X_0 Z_1.
let (coefficient, (paulis, idxQubits)) = (3.1, ([PauliX; PauliZ], [0, 1]));
我们也可以使用解构来访问用户定义类型的不同部分:
newtype Quaternion = (Double, Double, Double, Double);
let (realPart, iPart, jPart, kPart) = Quaternion(1.0, -2.0, 3.5, 0.0);