表达式
表达式 通过将运算符和函数应用于操作数来指定值的计算。
操作数和主表达式
操作数表示表达式中的基本值。
主表达式是一元和二元表达式的操作数。主表达式可以是字面量、表示变量的标识符或带括号的表达式。
PrimaryExpression = identifier | Literal | "(" Expression ")" .
字面量
字面量构造一个值。
Literal = int_lit
| float_lit
| string_lit
| regex_lit
| duration_lit
| date_time_lit
| pipe_receive_lit
| RecordLiteral
| ArrayLiteral
| DictLiteral
| FunctionLiteral .
记录字面量
记录字面量构造一个具有记录类型的值。
RecordLiteral = "{" RecordBody "}" .
RecordBody = WithProperties | PropertyList .
WithProperties = identifier "with" PropertyList .
PropertyList = [ Property { "," Property } ] .
Property = identifier [ ":" Expression ]
| string_lit ":" Expression .
示例
{a: 1, b: 2, c: 3}
{a, b, c}
{o with x: 5, y: 5}
{o with a, b}
数组字面量
数组字面量构造一个具有数组类型的值。
ArrayLiteral = "[" ExpressionList "]" .
ExpressionList = [ Expression { "," Expression } ] .
字典字面量
字典字面量构造一个具有 dict 类型的值。
DictLiteral = EmptyDict | "[" AssociativeList "]" .
EmptyDict = "[" ":" "]" .
AssociativeList = Association { "," AssociativeList } .
Association = Expression ":" Expression .
键可以是任意表达式。类型系统强制所有键的类型相同。
示例
a = "a"
b = [:] // empty dictionary
c = [a: 1, "b": 2] // dictionary mapping string values to integers
d = [a: 1, 2: 3] // type error: cannot mix string and integer keys
函数字面量
函数字面量 定义一个具有主体和参数的新函数。函数主体可以是块或单个表达式。如果函数主体是显式块,则必须具有 return 语句,否则表达式是返回值。
FunctionLiteral = FunctionParameters "=>" FunctionBody .
FunctionParameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = Parameter { "," Parameter } .
Parameter = identifier [ "=" Expression ] .
FunctionBody = Expression | Block .
函数字面量示例
() => 1 // function returns the value 1
(a, b) => a + b // function returns the sum of a and b
(x=1, y=1) => x * y // function with default values
(a, b, c) => { // function with a block body
d = a + b
return d / c
}
所有函数字面量都是匿名的。可以使用变量赋值为函数命名。
add = (a,b) => a + b
mul = (a,b) => a * b
函数字面量是闭包,可以引用在周围块中定义的变量。这些变量在函数字面量和周围块之间共享。
函数参数是命名的。没有位置参数。实现函数类型的值必须使用相同的参数名称。
apply = (f, x) => f(x: x)
apply(f: (x) => x + 1, x: 2) // 3
apply(f: (a) => a + 1, x: 2) // error, function must use the same argument name `x`.
apply(f: (x, a=3) => a + x, x: 2) // 5, extra default arguments are allowed
调用表达式
调用表达式 使用提供的参数调用函数。参数必须使用参数名称指定。不支持位置参数。参数顺序无关紧要。当参数具有默认值时,不需要指定它。
CallExpression = "(" PropertyList ")" .
调用表达式示例
f(a:1, b:9.6)
float(v:1)
当每个参数的名称与每个参数的名称匹配时,在调用表达式中使用简短表示法。
调用表达式中的简短表示法示例
add(a: a, b: b) //long notation
add(a, b) // short notation equivalent
add = (a,b) => a + b
a = 1
b = 2
// Don't mix short and long notation.
add(a: a, b)
add(a, b: b)
管道表达式
管道表达式 是具有隐式管道参数的调用表达式。管道表达式简化了创建长嵌套调用链。
管道表达式将左侧表达式的结果作为管道参数传递给右侧调用表达式。函数字面量指定使用管道字面量作为参数的默认值,来指定哪个参数(如果有)是管道参数。如果函数未声明管道参数,则使用管道表达式是错误的。
pipe_receive_lit = "<-" .
管道表达式示例
foo = () => // function body elided
bar = (x=<-) => // function body elided
baz = (y=<-) => // function body elided
foo() |> bar() |> baz() // equivalent to baz(x:bar(y:foo()))
索引表达式
索引表达式基于数字索引访问数组中的值。
IndexExpression = "[" Expression "]" .
成员表达式
成员表达式访问记录的属性。它们使用以下形式之一的表达式指定
rec.k
// or
rec["k"]
被访问的属性必须是标识符或字符串字面量。在任何一种情况下,字面量值都是被访问属性的名称,标识符不会被评估。无法使用任意表达式访问记录的属性。
如果 rec
包含属性为 k
的条目,则 rec.k
和 rec["k"]
都返回与 k
关联的值。如果 rec
不 包含属性为 k
的条目,则 rec.k
和 rec["k"]
都返回 null。
MemberExpression = DotExpression | MemberBracketExpression .
DotExpression = "." identifier .
MemberBracketExpression = "[" string_lit "]" .
条件表达式
条件表达式评估布尔值条件。如果结果为 true,则评估并返回 then
关键字后面的表达式。如果结果为 false,则评估并返回 else
关键字后面的表达式。在任何一种情况下,仅评估所采用的分支,并且仅发生与此分支关联的副作用。
ConditionalExpression = "if" Expression "then" Expression "else" Expression .
条件表达式示例
color = if code == 0 then "green" else if code == 1 then "yellow" else "red"
根据上面的定义,如果条件评估为 null 或未知值,则评估 else 分支。
运算符
运算符将操作数组合为表达式。下表给出了运算符的优先级。数字较低的运算符具有较高的优先级。
优先级 | 运算符 | 描述 |
---|---|---|
1 | a() | 函数调用 |
a[] | 成员或索引访问 | |
. | 成员访问 | |
2 | |> | 管道转发 |
3 | () => 1 | FunctionLiteral |
4 | ^ | 求幂 |
5 | * / % | 乘法、除法和取模 |
6 | + - | 加法和减法 |
7 | == != | 比较运算符 |
< <= | ||
> >= | ||
=~ !~ | ||
8 | not | 一元逻辑运算符 |
exists | Null 检查运算符 | |
9 | and | 逻辑与 |
10 | or | 逻辑或 |
11 | if then else | 条件 |
运算符优先级直接编码到语法中,如下所示。
Expression = ConditionalExpression .
ConditionalExpression = LogicalExpression
| "if" Expression "then" Expression "else" Expression .
LogicalExpression = UnaryLogicalExpression
| LogicalExpression LogicalOperator UnaryLogicalExpression .
LogicalOperator = "and" | "or" .
UnaryLogicalExpression = ComparisonExpression
| UnaryLogicalOperator UnaryLogicalExpression .
UnaryLogicalOperator = "not" | "exists" .
ComparisonExpression = MultiplicativeExpression
| ComparisonExpression ComparisonOperator MultiplicativeExpression .
ComparisonOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "=~" | "!~" .
AdditiveExpression = MultiplicativeExpression
| AdditiveExpression AdditiveOperator MultiplicativeExpression .
AdditiveOperator = "+" | "-" .
MultiplicativeExpression = ExponentExpression
| ExponentExpression ExponentOperator MultiplicativeExpression .
| ExponentExpression MultiplicativeOperator MultiplicativeExpression .
MultiplicativeOperator = "*" | "/" | "%" .
ExponentExpression = PipeExpression
| ExponentExpression ExponentOperator PipeExpression .
ExponentOperator = "^" .
PipeExpression = PostfixExpression
| PipeExpression PipeOperator UnaryExpression .
PipeOperator = "|>" .
UnaryExpression = PostfixExpression
| PrefixOperator UnaryExpression .
PrefixOperator = "+" | "-" .
PostfixExpression = PrimaryExpression
| PostfixExpression PostfixOperator .
PostfixOperator = MemberExpression
| CallExpression
| IndexExpression .
除以 0 或使用除数为 0 的 mod 运算符将导致错误。根据 IEEE-754 浮点规范,浮点除以零会产生正无穷大或负无穷大。
另请参阅 Flux 运算符。
此页是否对您有帮助?
感谢您的反馈!