5.4.6 计算

218 阅读5分钟

5.4.6 计算

这一章节描述 Reach 中所有场景下均可用的常见特征。

5.4.6.1 注释

// 单行注释/* 多行 * 注释 */

注释是会被编译器忽略的文本。以 // 开头直到行尾的文本构成单行注释。用 /* 和 */ 闭合的文本构成多行注释。在多行注释中嵌套多行注释无效的。

5.4.6.2 块

{ return 42; }{ const x = 31; return x + 11; }{ if ( x < y ) { return "Why"; } else { return "Ecks"; } }

块由一连串语句构成,这些语句被括号环绕,即 { 和 } 。

5.4.6.3 语句

本节描述在任何 Reach 场景中均可用的语句。

每一条语句都会影响后续语句的含义,语句的后续语句被称为其尾部。例如:若 {X;Y;Z;} 是一个,那么 X 的尾部是 {Y;Z;} ,Y 的尾部是 {Z;} 。

从程序源代码的结构来看,尾部是静态可见的,而延拓则受函数调用的影响。

不以终止语句(没有尾部语句)结尾的一系列语句,如 return 语句continue 语句exit 语句,均被视为以 return null; 结尾。

本节的剩余部分将列举每种语句

5.4.6.3.1 const 和 function

标识符定义要么是值定义,要么是函数定义。每一个标识符定义均会引入一个或多个绑定标识符。

const DELAY = 10;const [ Good, Bad ] = [ 42, 43 ];const { x, y } = { x: 1, y: 2 };const [ x, [ y ] ] = [ 1, [ 2 ] ];const [ x, { y } ] = [ 1, { y: 2 } ];const { x: [ a, b ] } = { x: [ 1, 2 ] };

有效标识符遵循与JavaScript标识符相同的规则:它们可以由Unicode字母数字字符、或 _ 或 $ 组成,但不能以数字开头。

值定义的格式为:const LHS = RHS; 。

LHS必须遵从以下语法规定:

LHS::=id
[‹LHS-tuple-seq›]
{‹LHS-obj-seq›}
LHS-tuple-seq::=
...‹LHS
LHS
LHS›,‹LHS-tuple-seq
LHS-obj-seq::=
...‹LHS
LHS-obj-elem
LHS-obj-elem›,‹LHS-obj-seq
LHS-obj-elem::=id
propertyName›:‹LHS
propertyName::=id
string
number
[‹expr›]

RHS 必须与 LHS 兼容。也就是说,如果 LHS 是一个 ‹LHS-tuple-seq› ,那么相应的 RHS 必须是一个元素数正确的元组。如果 LHS 是 ‹LHS-obj-seq› ,则相应的 RHS 必须是带有正确字段的对象。

这些在语句尾部可以作为相应的绑定标识符被调用。

function randomBool() { return (interact.random() % 2) == 0; };

函数定义的格式为: function FUN (LHS_0, ..., LHS_n) BLOCK; 它将 FUN 定义为一个函数,该函数将其 BLOCK 的函数主体抽象至左侧的 LHS_0 到 LHS_n 。

函数参数可以指定默认参数。用于实例化这些参数的表达式可以访问被定义的函数范围内的任意变量。此外,这些表达式可以引用函数定义中在它之前的参数。具有默认参数的参数必须位于所有其他参数之后。

function f(a, b, c = a + 1, d = b + c) => a + b + c + d; Reach 程序中的所有标识符必须在程序中被绑定的位置解除绑定,即,用新定义对标识符进行跟踪处理是无效的。例如: const x = 3;const x = 4;

无效的。不管绑定关系是否仅为单个参与者所知,该限制均生效。例如, Alice.only(() => { const x = 3; });Bob.only(() => { const x = 3; });

也是无效的。

特殊标识符 _ 是此规定的例外。 _ 总是被认为处于未绑定状态。这意味着 _ 既是一个永远无法被读取的标识符,也是一个可以多次绑定的标识符。这在忽略不需要的值时比较有用,例如: const [_, x, _] = [1, 2, 3];

5.4.6.3.2 return

return 17;return 3 + 4;return f(2, false);return;

return 语句的格式为 return EXPR; 。其中 EXPR 是计算出与 EXPR 相等的表达式。作为特例, return; 与 return null; 的意思相同。

return 语句将其值返回给被环绕着的函数应用。

return 语句终止语句,它必须有一个空尾。例如: { return 1; return 2; }

无效的,因为第一个 return尾部非空。

5.4.6.3.3 if

if ( 1 + 2 < 3 ) { return "Yes!";} else { return "No, waaah!"; }

这是一个条件语句,其格式为: if (COND) NOT_FALSE else FALSE 其中 COND 是一个表达式,NOT_FALSE 和 FALSE 是语句(很有可能是语句块),执行 NOT_FALSE 还是 FALSE 取决于 COND 的值是否等于 false

NOT_FALSE 和 FALSE 均具有空,即NOT_FALSE 和 FALSE 的尾部均只限定在其语句内。例如: if ( x < y ) { const z = 3; }else { const z = 4; }return z;

是错误的,因为标识符 z 并没有在条件语句之外被绑定。

条件语句存在于共识步骤中,只能在 NOT_FALSE 或 FALSE 中包含共识转移。因为其语句与条件语句本身均处于相同的场景中。

5.4.6.3.4 switch

const mi = Maybe(UInt).Some(42);switch ( mi ) { case None: return 8; case Some: return mi + 10; }switch ( mi ) { case None: return 8; default: return 41; }

switch 语句格式为:switch (VAR) { CASE ... },其中:VAR 是一个绑定数据实例的变量,CASE 要么是 case VARIANT: STMT ...( VARIANT 是一个变量),要么是 default: STMT ...,STMT 是一连串语句,根据 VAR 持有的变量选择对应的一连串语句。在 switch 的某个 case 主体部分,VAR 具备变量的类型。即在 Maybe(UInt) switch 的 一个 Some case 中,变量绑定了一个整型。

所有 case 均具有空,即 case 语句的尾部均只限定在该语句内。

switch 语句存在于共识步骤中,只能在 case 中包含共识转移。因为其语句与条件语句本身均处于相同的场景中。

同一 case 出现多次、或是 case 缺失、或是 case 多余(即某变量不存在于 VAR 的数据类型中),均是无效的。

5.4.6.3.5 块语句

当一个出现在语句位置时,块语句为该中的标识符定义建立一个局部的、单独的作用域。换句话说,含有的代码段是整体运作的,但是语句尾部与外围的尾部是隔离的。例如, const x = 4;return x;

结果是 4 ,但是 { const x = 4; }return x;

是错的,因为标识符 x 没有在块语句外部被绑定。

5.4.6.3.6 Try/Catch 和 Throw 语句

try { throw 10;} catch (v) { transfer(v).to(A); }

try 语句格式为:try BLOCK catch (VAR) BLOCK 。该语句允许在抛出异常时使用指定的处理程序执行代码块。

throw 语句格式为:throw EXPR ,该语句会将控制流传输到异常处理程序,并将 EXPR 和 VAR 绑定。可以存在的任何值均能被抛出。例如:Ints 和 Arrays 是可以被抛出的有效值。但函数不是。

5.4.6.3.7 表达式语句

4;f(2, true);

一个处于语句位置的表达式 E 等价于块语句 {return E; } 。

te.html?#%28reach.%28%28.Array%29%29%29).zip(x, y)x.zip(y) Array.zip(x,y) 返回一个长度与 x 和 y(x 和 y 长度必须相同)相同的新数组,该新数组的元素是由 x 和 y 的元素构成的元组。这可以简写成 x.zip(y) 。 #%28reach.%28%28.Null%29%29%29),                    Spicy: Null,                    Sweet: Null,                    Umami: Null}); const burger = Taste.Umami(); #%28reach._%28%28const%29%29%29) nice = Shape.Circle({r: 5});

数据实例写作 DATA.VARIANT(VALUE) ,其中 DATA 是 Data 类型,VARIANT 是 DATA 的变量中某一个的名称, VALUE 是匹配变量类型的值。作为一种特殊情况,当变量的类型为 Null 时,可以省略该值,如上文中 burger 的定义所示。

数据实例用于 switch 语句。