Подтвердить что ты не робот

Когда фигурные скобки необязательны в синтаксисе лямбда Java 8?

Я понимаю, что реализация лямбда Java 8 может быть изменена, но в lambda build b39 я обнаружил, что фигурные скобки могут быть опущены только тогда, когда выражение лямбда возвращает непустой тип. Например, это компилируется:

public class Collections8 {
        public static void main(String[] args) {
                Iterable<String> names = Arrays.asList("Alice", "Bob", "Charlie");
                names.filter(e -> e.length() > 4).forEach(e -> { System.out.println(e); });
        }
}

Но удаляем фигурные скобки следующим образом:

names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));

дает ошибку

Collections8.java:6: error: method forEach in interface Iterable<T> cannot be applied to given types;
        names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));
                                         ^
  required: Block<? super String>
  found: lambda
  reason: incompatible return type void in lambda expression
  where T is a type-variable:
    T extends Object declared in interface Iterable

Может ли кто-нибудь объяснить, что здесь происходит?

4b9b3361

Ответ 1

Вы можете опустить фигурные скобки, когда тело лямбда является единственным выражением или вызовом метода void. Каждое выражение оценивает значение и, следовательно, не может быть недействительным.

Если тело лямбда является блоком операторов (например, серия вычислений, за которой следует оператор return), или лямбда не имеет значения (т.е. имеет тип возврата void) и не является ни одной void, вы должны использовать форму блока, для которой требуются скобки.

В блочной лямбда, если значение return ed, то все возможные пути кода должны либо return a, либо throw a Throwable.

Ответ 2

Это только в: EG имеет (в основном) решение по синтаксису.

Рассмотрев ряд альтернатив, мы решили существенно принять синтаксис С#. Мы все еще можем более подробно обсуждать тонкости (например, тонкая стрелка против стрелки жира, специальная нильская форма и т.д.), и не имеют но приходят к решению по синтаксису ссылок метода.

Синтаксис С#:

lambda = ArgList Arrow Body
ArgList = Identifier
           | "(" Identifier [ "," Identifier ]* ")"
           | "(" Type Identifier [ "," Type Identifier ]* ")"
Body = Expression
           | "{" [ Statement ";" ]+ "}"

Выражение что-то оценивает, вы не можете иметь недействительные выражения в Java. Это утверждение, поэтому вам нужно {} вокруг него.

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html

Ответ 3

Если скобок нет, то лямбда автоматически возвращает одно выражение после оператора → . Таким образом, когда у вас есть лямбда, которая ничего не возвращает, вы должны использовать фигурные скобки

Ответ 4

Я пробовал свой код и для самой современной версии JRE. Думаю, все будет хорошо.

Ниже я ссылаюсь на документы Oracle Java.

В выражении лямбда вы должны заключать выражения в фигурные скобки ({}). Однако вам не нужно вставлять вызов void-метода в фигурные скобки.
Например, следующее действительное выражение лямбда:

email -> System.out.println(email)

И док объясняет довольно ясно. Надеюсь, это может решить вашу проблему.

Ссылки: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Ответ 5

Java лямбда-выражения улучшены с помощью основных правил,

  • Для одного аргумента скобки необязательны [например: a → aa; (а) → ab; ]
  • Для нуля или более одного аргумента скобки обязательны [например:() → 10; а → а * а; (а, б) → а + б; ]
  • Для одной строки выражения фигурные скобки необязательны [например: a → aa; a → {return aa}; ]
  • или одна строка выражения ключевое слово return не является обязательным [например: a → aa; a → {return aa}; ]

Есть больше правил, которые вы можете соблюдать в Основы Лямбда-выражения в Java 8