箭头(->)运算符 precedence/priority 是最低的,还是 assignment/combined 赋值的优先级最低?
Arrow (->) operator precedence/priority is lowest, or priority of assignment/combined assignment is lowest?
JLS:
The lowest precedence operator is the arrow of a lambda expression
(->), followed by the assignment operators.
遵循哪个方向(增加优先级,降低优先级)? - "followed" 表示赋值具有更高的优先级或更低的优先级(相对于箭头运算符)?我猜,在增加,因为 "lowest" (对于箭头)意味着绝对最低。
据我了解,箭头 (->) 应该位于此 Princeton 运算符优先级 table 的最底部(即低于所有赋值运算符),因此箭头 (->) 具有0(零)优先级(根据 table)。
我的理解正确吗?
ExamTray 似乎说箭头优先级至少与赋值相同...另外澄清箭头关联性是左->到->右(与赋值不同)。我没有找到任何关于箭头关联性的 JLS 引用。
我一直认为分配优先级原则上是最低的,这是有原因的。
首先,让我们在这里解释一下实际问题。
假设您的定义类似于
IntUnaryOperator op;
以下语法被接受,并按预期工作:
op = x -> x;
也就是说,我们在 int
上有一个恒等函数分配给 op
变量。但是,如果 =
具有更高的优先级,我们希望 Java 将其解释为
(op = x) -> x;
这在语法上无效,因此应该是编译错误。因此,在实践中,赋值并不比箭头具有更高的优先级。
但是下面这样也行(假设t
是一个class/instance类型的int
变量):
op = x -> t = x;
这会编译,并且函数(如果应用)会将操作数的值分配给 t
以及 returns 它。
这意味着箭头的优先级不高于赋值 t = x
。否则它会被解释为
op = ( x -> t ) = x
很明显,事实并非如此。
所以看起来这些操作具有相同的优先级。更重要的是,它们是右结合的。 JLS chapter 19:
处的语法暗示了这一点
Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block
所以 lambda 主体的右侧让我们回到 Expression
,这意味着我们可以在其中有一个(更高优先级)lambda,或者在其中有一个(更高优先级)赋值。我所说的 "higher priority" 的意思是,您对产生式规则的了解越深,表达式的计算就越早。
赋值运算符也是如此:
AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression
再一次,赋值的右边把我们带回到 Expression
,所以我们可以在那里有一个 lambda 表达式或赋值。
因此,语法为我们提供了对情况的明确描述,而不是依赖于 JLS 文本。
注意引用 JLS text 之前的句子:
Precedence among operators is managed by a hierarchy of grammar productions.
Java 语言的语法决定了哪些结构是可能的,并且隐含地决定了运算符的优先级。
即使是您链接的 princeton table 状态:
There is no explicit operator precedence table in the Java Language Specification. Different tables on the web and in textbooks disagree in some minor ways.
因此,Java 语言的语法不允许在赋值运算符左侧使用 lambda 表达式,同样,也不允许在 ->
左侧进行赋值。因此,这些运算符之间没有歧义,优先规则虽然在 JLS 中明确说明,但变得毫无意义。
这允许编译,例如这样的gem,没有歧义:
static Consumer<String> C;
static String S;
public static void main(String[] args)
{
Runnable r;
r = () -> C = s -> S = s;
}
JLS:
The lowest precedence operator is the arrow of a lambda expression (->), followed by the assignment operators.
遵循哪个方向(增加优先级,降低优先级)? - "followed" 表示赋值具有更高的优先级或更低的优先级(相对于箭头运算符)?我猜,在增加,因为 "lowest" (对于箭头)意味着绝对最低。
据我了解,箭头 (->) 应该位于此 Princeton 运算符优先级 table 的最底部(即低于所有赋值运算符),因此箭头 (->) 具有0(零)优先级(根据 table)。
我的理解正确吗?
ExamTray 似乎说箭头优先级至少与赋值相同...另外澄清箭头关联性是左->到->右(与赋值不同)。我没有找到任何关于箭头关联性的 JLS 引用。
我一直认为分配优先级原则上是最低的,这是有原因的。
首先,让我们在这里解释一下实际问题。
假设您的定义类似于
IntUnaryOperator op;
以下语法被接受,并按预期工作:
op = x -> x;
也就是说,我们在 int
上有一个恒等函数分配给 op
变量。但是,如果 =
具有更高的优先级,我们希望 Java 将其解释为
(op = x) -> x;
这在语法上无效,因此应该是编译错误。因此,在实践中,赋值并不比箭头具有更高的优先级。
但是下面这样也行(假设t
是一个class/instance类型的int
变量):
op = x -> t = x;
这会编译,并且函数(如果应用)会将操作数的值分配给 t
以及 returns 它。
这意味着箭头的优先级不高于赋值 t = x
。否则它会被解释为
op = ( x -> t ) = x
很明显,事实并非如此。
所以看起来这些操作具有相同的优先级。更重要的是,它们是右结合的。 JLS chapter 19:
处的语法暗示了这一点Expression:
LambdaExpression
AssignmentExpression
LambdaExpression:
LambdaParameters -> LambdaBody
...
LambdaBody:
Expression
Block
所以 lambda 主体的右侧让我们回到 Expression
,这意味着我们可以在其中有一个(更高优先级)lambda,或者在其中有一个(更高优先级)赋值。我所说的 "higher priority" 的意思是,您对产生式规则的了解越深,表达式的计算就越早。
赋值运算符也是如此:
AssignmentExpression:
ConditionalExpression
Assignment
Assignment:
LeftHandSide AssignmentOperator Expression
再一次,赋值的右边把我们带回到 Expression
,所以我们可以在那里有一个 lambda 表达式或赋值。
因此,语法为我们提供了对情况的明确描述,而不是依赖于 JLS 文本。
注意引用 JLS text 之前的句子:
Precedence among operators is managed by a hierarchy of grammar productions.
Java 语言的语法决定了哪些结构是可能的,并且隐含地决定了运算符的优先级。
即使是您链接的 princeton table 状态:
There is no explicit operator precedence table in the Java Language Specification. Different tables on the web and in textbooks disagree in some minor ways.
因此,Java 语言的语法不允许在赋值运算符左侧使用 lambda 表达式,同样,也不允许在 ->
左侧进行赋值。因此,这些运算符之间没有歧义,优先规则虽然在 JLS 中明确说明,但变得毫无意义。
这允许编译,例如这样的gem,没有歧义:
static Consumer<String> C;
static String S;
public static void main(String[] args)
{
Runnable r;
r = () -> C = s -> S = s;
}