表达式
一个 表达式 通过将运算符和函数应用于操作数来指定值的计算。
操作数和主要表达式
操作数表示表达式中的基本值。
主要表达式是单元和双元表达式的操作数。 主要表达式可以是文字、表示变量的标识符或带括号的表达式。
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
函数字面量
一个 函数字面量 定义了一个具有主体和参数的新函数。 函数主体可以是一个块或一个单一的表达式。 如果它是一个显式块,函数主体必须有一个返回语句,否则表达式就是返回值。
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)
管道表达式
A pipe expression 是一个带有隐式管道参数的调用表达式。管道表达式简化了创建长的嵌套调用链。
管道表达式将左侧表达式的结果作为管道参数传递给右侧调用表达式。函数字面量指定任何参数是否为管道参数,使用管道字面量作为参数的默认值。如果函数没有声明管道参数,则使用管道表达式会导致错误。
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 | 函数字面量 |
| 4 | ^ | 指数运算 |
| 5 | * / % | 乘法、除法和取模 |
| 6 | + - | 加法和减法 |
| 7 | == != | 比较运算符 |
< <= | ||
> >= | ||
=~ !~ | ||
| 8 | not | 一元逻辑运算符 |
exists | 空检查运算符 | |
| 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将导致错误。 浮点数除以零会根据IEEE-754浮点数规范产生正无穷大或负无穷大。
另见 Flux Operators.