62
задан 2 April 2018 в 20:44

6 ответов

От JEP Вывода Типа локальных переменных:

процесс вывода, существенно, просто дает переменной тип своего выражения инициализатора. Некоторая тонкость:

  • инициализатор не имеет никакого целевого типа (потому что мы еще не вывели его). Выражения Poly, которые требуют такого типа, как [1 114] лямбды , ссылки метода, и выстраивают инициализаторы, инициируют ошибку.

, поскольку лямбда-выражение отдельно не имеет типа, оно не может быть выведено для var.

<час>

... Точно так же правило по умолчанию могло быть установлено.

Несомненно, можно придумать способ работать вокруг этого ограничения. Почему разработчики приняли решение не сделать, который является действительно до предположения, если кто-то, кто был частью принятия решений, не может ответить здесь. Если Вам интересно так или иначе, Вы могли бы спросить об этом в одном из openjdk списков рассылки: http://mail.openjdk.java.net/mailman/listinfo

, Если я должен был предположить, они, вероятно, не хотели связывать вывод лямбды в контексте var к определенному набору функциональных интерфейсных типов, которые исключат любое третье лицо функциональные интерфейсные типы. Лучшее решение состояло бы в том, чтобы вывести тип родовой функции (т.е. (Apple) -> boolean), который может, чем быть преобразованным в совместимый функциональный интерфейсный тип. Но JVM не имеет таких функциональных типов, и решение не реализовать их было уже принято во время проекта, который создал лямбда-выражения. Снова, если Вы интересуетесь конкретными причинами, спрашиваете devs.

54
ответ дан 31 October 2019 в 13:32

Это не имеет никакого отношения var. Это имеет отношение, имеет ли лямбда автономный тип . Путь var работы состоят в том, что он вычисляет автономный тип инициализатора на RHS и выводит это.

Начиная с их введения в Java 8, лямбда-выражения и ссылки метода не имеют никакого автономного типа - они требуют целевой тип , который должен быть функциональным интерфейсом.

, Если Вы пробуете:

Object o = (String s) -> s.length();

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

Просьба о выводе с var просто мешает, но так как на более легкий вопрос нельзя ответить, более твердый не может также.

Примечание, что Вы могли обеспечить целевой тип другими средствами (такими как бросок) и затем они будут работать:

var x = (Predicate<String>) s -> s.isEmpty();

, потому что теперь RHS имеет автономный тип. Но Вы - более обеспеченное обеспечение целевого типа путем предоставления x явный тип.

57
ответ дан 31 October 2019 в 13:32

Всем, кто говорит, это невозможно, нежелательно, или нежелательно, я просто хочу указать, что Scala может вывести тип лямбды путем определения только типа аргумента:

val predicateVar = (apple: Apple) => apple.getColor().equals("red")

И в Haskell, потому что getColor была бы автономная функция, не присоединенная к объекту, и потому что это делает полный вывод Хиндли-Milner, Вы не должны указывать даже тип аргумента:

predicateVar = \apple -> getColor apple == "red"

Это чрезвычайно удобно, потому что это не простые типы, которые являются раздражающими, чтобы программисты явно указали, это - более сложные.

, Другими словами, это не функция в Java 10. Это - ограничение их реализации и предыдущих проектных решений.

27
ответ дан 31 October 2019 в 13:32

Как несколько человек уже упомянули, что должен вывести тип var и почему должен он?

оператор:

var predicateVar = apple -> apple.getColor().equals("red");

неоднозначно и нет никакой допустимой причины, почему компилятор должен выбрать Function<Apple, Boolean> более чем Predicate<Apple> или наоборот принятие apple, идентификатор в лямбде представляет Apple экземпляр.

Другая причина состоит в том, что лямбда в его собственном не имеет тип speakable следовательно нет никакого пути к компилятору для выведения его.

кроме того, , "если бы это было возможно" , воображают издержки, поскольку компилятор должен был бы пройти все функциональные интерфейсы и определить, какой функциональный интерфейс является самым соответствующим каждый раз, когда Вы присваиваете лямбду var переменная.

5
ответ дан 31 October 2019 в 13:32

Для ответа на это, мы должны сообщить подробности и понять то, что лямбда и как она работает.

Первый мы должны понять, какова лямбда:

лямбда-выражение А всегда реализует функциональный интерфейс, так, чтобы, когда необходимо предоставить функциональный интерфейс как Runnable, вместо того, чтобы иметь необходимость создать совершенно новый класс, который реализует интерфейс, можно было просто использовать синтаксис лямбды для создания метода, которого требует функциональный интерфейс. Следует иметь в виду, хотя это, лямбда все еще имеет тип функционального интерфейса, который это реализует.

, Имея это в виду, позволяет, берут это шаг вперед:

Это работает отлично как в случае Выполнимого, я могу просто создать новый поток как это new Thread(()->{//put code to run here}); вместо того, чтобы создать совершенно новый объект реализовать функциональный интерфейс. Это работает, так как компилятор знает, что Thread() берет объект Выполнимого типа, таким образом, он знает то, что вводит лямбда-выражение, должен быть.

Однако в случае присвоения лямбды к локальной переменной, компилятор не имеет никакой подсказки, какой функциональный интерфейс эта лямбда реализует так, это не может вывести, каков тип var должен быть. Так как, возможно, это реализует функциональный интерфейс созданный пользователь, или возможно это эти runnable интерфейс, нет только никакого способа знать.

Поэтому лямбды не работают с ключевым словом var.

4
ответ дан 31 October 2019 в 13:32

Поскольку это - нефункция:

Эта обработка была бы ограничена локальными переменными с инициализаторами, индексами в расширенном для цикла, и местные жители, объявленные в традиционном для цикла; это не было бы доступно для метода formals, конструктор formals, типы возврата метода, поля, поймало бы formals или любой другой вид объявления переменной.

http://openjdk.java.net/jeps/286

2
ответ дан 31 October 2019 в 13:32

Другие вопросы по тегам:

Похожие вопросы: