你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

上下文表达式和省略表达式

上下文表达式是仅在某些上下文中有效的表达式,例如,在 复制和更新表达式中使用项名称 而无需限定它们。

当编译器可以推断和自动插入表达式(例如 计算和重新分配语句)时,可以省略表达式

开放式范围是适用于上下文表达式和省略表达式的另一个示例。 它们仅在特定上下文中有效,编译器通过推断合适的边界在编译过程中将它们转换为普通 Range 表达式。

Range 类型的值生成一系列整数,由起始值、步骤值(可选)和结束值指定。 例如,Range 文本表达式 1..3 生成序列 1,2,3。 同样,表达式 3..-1..1 生成序列 3,2,1。 还可以使用范围通过切片从现有数组创建新的数组,例如:

    let arr = [1,2,3,4];
    let slice1 = arr[1..2..4];  // contains [2,4] 
    let slice2 = arr[2..-1..0]; // contains [3,2,1]

不能在 Q#中定义无限范围;始终需要指定起始值和结束值。 唯一的例外是使用 Range 来切片数组。 在这种情况下,编译器可以合理推断范围的开始或结束值。

在上一个数组切片示例中,编译器可以假定预期范围结束应该是数组中最后一项的索引(如果步骤大小为正)。 如果步骤大小为负数,则范围结束可能是数组中第一项的索引,0。 相反的保留范围开头。

总之,如果省略范围起始值,则推断的起始值

  • 如果未指定步骤或指定的步骤为正,则为零。
  • 如果指定的步骤为负数,则为数组的长度减去一个。

如果省略范围结束值,则推断的结束值

  • 如果未指定任何步骤或指定的步骤为正,则数组的长度减去一个。
  • 如果指定的步骤为负数,则为零。

因此,Q# 允许在数组切片表达式中使用开放式范围,例如:

let arr = [1,2,3,4,5,6];
let slice1  = arr[3...];      // slice1 is [4,5,6];
let slice2  = arr[0..2...];   // slice2 is [1,3,5];
let slice3  = arr[...2];      // slice3 is [1,2,3];
let slice4  = arr[...2..3];   // slice4 is [1,3];
let slice5  = arr[...2...];   // slice5 is [1,3,5];
let slice7  = arr[4..-2...];  // slice7 is [5,3,1];
let slice8  = arr[...-1..3];  // slice8 is [6,5,4];
let slice9  = arr[...-1...];  // slice9 is [6,5,4,3,2,1];
let slice10 = arr[...];       // slice10 is [1,2,3,4,5,6];

由于确定范围步骤在运行时是正的还是负的,因此编译器会插入在运行时计算的合适表达式。 对于省略的结束值,插入的表达式为 step < 0 ? 0 | Length(arr)-1,对于省略的起始值,则为 step < 0 ? Length(arr)-1 | 0,其中 step 为范围步骤提供的表达式;如果未指定步骤,则为 1