Несколько пользователей для скрипта приложения Google?

Вывод по типу lambda не может зависеть от тела лямбда.

Компилятор сталкивается с трудной задачей, пытаясь понять неявные лямбда-выражения

    foo( value -> GIBBERISH )

Тип value должен быть выведен первым до того, как GIBBERISH может быть скомпилирован, поскольку в целом интерпретация GIBBERISH зависит от определения value.

(В вашем специальном случае GIBBERISH оказывается простой константой, независимой от value.)

Javac должен сначала вывести Value<T> для параметра value; в контексте нет ограничений, поэтому T=Object. Затем тело лямбда true скомпилировано и распознается как логическое, совместимое с T.

После того, как вы внесли изменение в функциональный интерфейс, тип параметра лямбда не требует вывода; T остается неосновным. Затем тело лямбда скомпилировано, и тип возврата выглядит как Boolean, который устанавливается как нижняя граница для T.


Еще один пример, демонстрирующий проблему

<T> void foo(T v, Function<T,T> f) { ... }

foo("", v->42);  // Error. why can't javac infer T=Object ?

T, считается String; тело лямбды не принимало участия в выводе.

В этом примере поведение Javac кажется нам очень разумным; это, вероятно, предотвратило ошибку программирования. Вы не хотите, чтобы вывод был слишком сильным; если все, что мы пишем, компилируется каким-то образом, мы потеряем доверие к ошибкам компилятора для нас.


Существуют и другие примеры, когда тело лямбда, как представляется, обеспечивает однозначные ограничения, однако компилятор не может использовать эту информацию , В Java сначала должны быть определены типы параметров лямбда, прежде чем можно будет рассмотреть тело. Это преднамеренное решение. Напротив, C # хочет попробовать разные типы параметров и посмотреть, что делает компиляцию кода. Java считает это слишком рискованным.

В любом случае, когда неявная лямбда не выполняется, что происходит довольно часто, укажите явные типы для лямбда-параметров; в вашем случае (Value<Boolean> value)->true

0
задан zx485 13 July 2018 в 21:39
поделиться