矢印(->)演算子の優先順位/優先順位が最も低いか、割り当て/組み合わせ割り当ての優先順位が最も低いですか?


18

JLS

最も優先順位低い演算子は、ラムダ式の矢印(->)でその後に代入演算子が続きます。

どちらの方向に進んだか(優先度の増加、優先度の減少)?-「フォロー済み」とは、割り当てが(矢印演算子に対して)優先度が高いか低いかを意味します。「最低」(矢印)は絶対最低を意味するので、増加すると思います。

私が理解しているように、矢印(->)はこのプリンストン演算子の優先順位表の一番下(つまり、すべての代入演算子の下にあります)にある必要があります。

私の理解は正しいですか?

ExamTrayは、矢印の優先順位は少なくとも割り当てと同じであると言っているようです...さらに、矢印の結合性は(割り当てとは異なり)左→右→右であることを明確にしました。矢印の結合性に関するJLSの引用は見つかりませんでした。

私はいつも、割り当ての優先順位は主に理由により最低だと思っていました。


5
The lowest precedence operator is the arrow of a lambda expression.
カヤマン

2
はい、あなたの理解は正しいです。
エラン

4
場合は->低いEST、代入演算子は低い持つことができないのERの優先順位を。
アンディターナー

IntFunction fo = a->b->a-b; // in test 一般に->の優先度/関連性を意味します。そこで、全体の優先順位/関連性の表で、優先順位/関連性の場所を明確にすることに決めました。
コード完成

1
@glglglあなたの例IntUnaryOperator op; op = x -> x;は興味深いです。プロダクションの有効なインスタンスではない(op = x) -> xため、おそらく考慮されop = xませんLambdaParametersか?
アンディターナー

回答:


13

引用されたJLSテキストの前の文に注意してください。

演算子間の優先順位は、文法生成の階層によって管理されます。

Java言語の文法は、どの構造が可能で暗黙的に演算子の優先順位であるかを決定します。

あなたがリンクしたプリンストンテーブルでさえ:

Java言語仕様には、明示的な演算子優先順位表はありません。Web上と教科書内の異なる表は、いくつかのマイナーな方法で意見が異なります。

したがって、Java言語の文法では、代入演算子の左側にラムダ式を使用できません。同様に、の左側に代入を使用できません->。したがって、これらの演算子の間に曖昧さはなく、優先順位ルールはJLSで明示的に述べられていても意味がなくなります。

これは、曖昧さなしに、例えばそのような宝石をコンパイルすることを可能にします:

static Consumer<String> C;
static String S;
public static void main(String[] args)
{
  Runnable r;
  r = () -> C = s -> S = s;
}

10

まず、実際の問題をここで説明しましょう。

次のような定義があると仮定します

IntUnaryOperator op;

以下は構文的に受け入れられ、期待どおりに機能します。

op = x -> x;

つまりintop変数に割り当てられた恒等関数があります。しかし、=優先度が高い場合、Javaはこれを

(op = x) -> x;

これは構文的に有効ではないため、コンパイルエラーになります。したがって、割り当ては実際には矢印よりも優先されません。

しかし、以下も問題ありません(t型のクラス/インスタンス変数であると想定していますint)。

op = x -> t = x;

これはコンパイルされ、関数が適用されている場合は、オペランドの値が割り当てられてt返されます。

つまり、矢印は割り当てよりも優先されませんt = x。そうでなければ、次のように解釈されます。

op = ( x -> t ) = x

そして明らかに、これは何が起こるかではありません。

したがって、操作の優先順位は同じであるようです。さらに、それらは右連想です。これは、JLSの第19章の文法から暗示されています。

Expression:
  LambdaExpression
  AssignmentExpression

LambdaExpression:
  LambdaParameters -> LambdaBody

...

LambdaBody:
  Expression
  Block

したがって、ラムダ本体の右側からExpressionに戻ります。つまり、その中に(優先順位の高い)ラムダを含めるか、その中に(優先順位の高い)ラムダを割り当てることができます。「優先度が高い」とは、プロダクションルールを深く掘り下げるほど、式が早く評価されるということです。

同じことが代入演算子にも当てはまります。

AssignmentExpression:
  ConditionalExpression
  Assignment

Assignment:
  LeftHandSide AssignmentOperator Expression

ここでも、割り当ての右側からExpressionに戻るので、ラムダ式または割り当てをここに置くことができます。

したがって、JLSテキストに依存するのではなく、文法は状況を明確に説明しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.