Ссылки функций и лямбда

Я сталкиваюсь с ошибкой компиляции при попытке использовать ссылки lambdas / function с kotlin:

class Foo { fun getFilteredList(){ val numbers = listOf(1, 2, 3) numbers.filter(::isOdd) // prints [1, 3] } fun isOdd(x: Int): Boolean = x % 2 != 0 } 

Но я получаю ошибку времени компиляции, говоря о несоответствии типа:

Ошибка: (18, 16) Gradle: Ошибка ввода типа: inline fun kotlin.Iterable.filter (предикат: (T) -> kotlin.Boolean): kotlin.List нельзя применить к получателю: kotlin.List аргументы: (kotlin. reflect.KFunction2) Ошибка: (18, 23) Gradle: Тип несоответствия: выведенный тип kotlin.reflect.KFunction2 but (kotlin.Int) -> ??? (18, 23) Gradle: Тип несоответствия: выводный тип – kotlin.reflect.KFunction2, но (kotlin.Int) -> kotlin.Boolean ожидалось Ошибка: (18, 25) Gradle: Левая часть вызываемая ссылка с параметром приемника не может быть пустым. Укажите тип приемника до «::» явно

Я не уверен, что такое ошибка, и какой тип я должен явно указывать перед '::'

Другой вопрос: могу ли я использовать другую функцию объектов в качестве ссылки в котлин? Что-то вроде этого:

 class Bar { fun isOdd(x: Int): Boolean = x % 2 != 0 } class Foo { fun getFilteredList(){ val bar = Bar() val numbers = listOf(1, 2, 3) numbers.filter(bar::isOdd) // Use Bar's method } } 

Во втором примере: да, опорный синтаксис связанной функции поддерживается с Kotlin 1.1, поэтому вы можете написать bar::isOdd аналогично Java.

В первом примере ошибка пытается сказать, что isOdd на самом деле является функцией двух параметров (типов Foo и Int ), а передача функции, принимающей два параметра в качестве аргумента, тип которого является функцией одного параметра, недопустима. Чтобы сделать пример компиляции, вы можете сделать isOdd верхней или локальной функцией, которая сделает ее функцией одного параметра типа Int . Или, если вы используете Kotlin 1.1+, используйте ссылочный синтаксис связанной функции и просто напишите this::isOdd .

Забавно. «Java ударяет». ха-ха

Ваша проблема проста: вы объявили isOdd в классе Foo , правильно? Тогда это не функция , а метод . Это означает, что для этого требуется экземпляр Foo ( this ссылка), поэтому он является функцией из двух параметров: Foo.(Int) -> Boolean . И синтаксическая ошибка показывает, что ссылка на метод выглядит как Foo::isOdd .

В любом случае, объявление нестатического метода, который не использует объект, является антипаттерном даже в Java, не согласны ли вы?

Проблема может быть решена путем объявления свободной функции без класса или путем ее расширения: fun Int.isOdd()

PS Что касается второго вопроса – эта функция еще не поддерживается.

Intereting Posts
Основы программирования Котлина Котлин строит, вызывая JVM к ошибке сегментации Kotlin – Перегрузка оператора вызовом оператора Kotlin генерирует конструктор, который устанавливает значения по умолчанию для нулевых аргументов Запустить службу в фоновом режиме Не удалось запустить модульные тесты в новом проекте Android Kotlin Реализовать Hashmap с разными типами значений в Котлине Ошибка Kotlin при ссылке на активность из внутреннего класса Как настроить значок (drawable) для кнопки в anko? Kotlin: Как запустить функцию с задержкой с помощью функции расширения между объектом и GoogleMap в kotlin Kotlin – Идиоматический способ проверки массива содержит значение Что такое многостраничное текстовое разделение текста приложения Как я могу использовать составной ключ в Kotlin? В Vertx мне нужно перенаправить все HTTP-запросы на один и тот же URL-адрес, но для HTTPS