web-dev-qa-db-fra.com

Flèche (->) la priorité / priorité de l'opérateur est la plus faible, ou la priorité de l'affectation / affectation combinée est la plus faible?

JLS :

L'opérateur de priorité la plus basse est la flèche d'une expression lambda (->), suivie par les opérateurs d'affectation.

Suivi dans quelle direction (priorité croissante, priorité décroissante)? - "suivi" signifie que l'affectation a une priorité plus élevée ou une priorité plus faible (par rapport à l'opérateur de la flèche)? Je suppose, en augmentant, parce que "le plus bas" (pour la flèche) signifie absolument le plus bas.

Si je comprends bien, la flèche (->) devrait être tout en bas de cette table de priorité des opérateurs Princeton (qui est en dessous de tous les opérateurs d'affectation), donc la flèche (->) ayant un niveau de priorité 0 (zéro) (selon ce tableau).

Ai-je raison de comprendre?

ExamTray semble dire que la priorité de la flèche est au moins la même que celle de l'affectation ... De plus, elle a précisé que l'associativité de la flèche est Gauche-> À-> Droite (contrairement à l'affectation). Je n'ai trouvé aucune citation JLS pour l'associativité des flèches.

J'ai toujours pensé que la priorité d'affectation est principalement la plus basse pour une raison.

18
Code Complete

Notez la phrase précédant la citation texte JLS :

La priorité parmi les opérateurs est gérée par une hiérarchie de productions grammaticales.

La grammaire du langage Java détermine les constructions possibles et implicitement, la priorité de l'opérateur.

Même le table princeton vous avez lié des états:

Il n'y a pas de table de priorité d'opérateur explicite dans la spécification de langage Java. Différentes tables sur le Web et dans les manuels scolaires sont en désaccord de quelques manières mineures.

Ainsi, la grammaire du langage Java Java n'autorise pas les expressions lambda à gauche d'un opérateur d'affectation et, de même, n'autorise pas les affectations à gauche du ->. Il n'y a donc pas d'ambiguïté possible entre ces opérateurs et la règle de priorité, bien qu'explicitement énoncée dans le JLS, perd tout son sens.

Cela permet de compiler, par ex. un tel bijou, sans ambiguïté:

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

Tout d'abord, expliquons le problème pratique ici.

En supposant que vous ayez une définition comme

IntUnaryOperator op;

La syntaxe suivante est acceptée et fonctionne comme prévu:

op = x -> x;

Autrement dit, nous avons une fonction d'identité sur int affectée à la variable op. Mais si = avait une priorité plus élevée, nous nous attendons à ce que Java interprète cela comme

(op = x) -> x;

Ce qui n'est pas syntaxiquement valide, devrait donc être une erreur de compilation. Par conséquent, l'affectation n'a pas, en pratique, une priorité plus élevée que la flèche.

Mais ce qui suit est également OK (supposons que t est une variable de classe/instance de type int):

op = x -> t = x;

Cela compile et la fonction, si elle est appliquée, affecte la valeur de l'opérande à t et la renvoie également.

Cela signifie que la flèche n'a pas une priorité plus élevée que l'affectation t = x. Sinon, il aurait été interprété comme

op = ( x -> t ) = x

et clairement, ce n'est pas ce qui se passe.

Il semble donc que les opérations aient la même priorité. De plus, ils sont associatifs à droite. Ceci est impliqué par la grammaire de JLS chapitre 19 :

Expression:
  LambdaExpression
  AssignmentExpression

LambdaExpression:
  LambdaParameters -> LambdaBody

...

LambdaBody:
  Expression
  Block

Ainsi, le côté droit du corps lambda nous ramène à Expression, ce qui signifie que nous pouvons y avoir un lambda (de priorité plus élevée), ou une affectation (de priorité plus élevée). Ce que je veux dire par "priorité plus élevée", c'est que plus vous approfondissez les règles de production, plus tôt l'expression sera évaluée.

Il en va de même pour l'opérateur d'affectation:

AssignmentExpression:
  ConditionalExpression
  Assignment

Assignment:
  LeftHandSide AssignmentOperator Expression

Encore une fois, le côté droit de l'affectation nous renvoie à Expression, nous pouvons donc y avoir une expression lambda ou une affectation.

Ainsi, plutôt que de s'appuyer sur le texte JLS, la grammaire nous donne une description bien définie de la situation.

10
RealSkeptic