Я создал интерфейс:
interface ProgressListener {
fun transferred(bytesUploaded: Long)
}
но можно использовать его только как анонимный класс, а не лямбда
dataManager.createAndSubmitSendIt(title, message,
object : ProgressListener {
override fun transferred(bytesUploaded: Long) {
System.out.println(bytesUploaded.toString())
}
})
Я думаю, что это должна быть возможность заменить лямбда:
dataManager.createAndSubmitSendIt(title, message, {System.out.println(it.toString())})
Но я получаю сообщение об ошибке: несоответствие типов; необходимо - ProgressListener, нашли - () -> единица?
Что я делаю не так?
Как @zsmb13 сказал, преобразования Сэм поддерживаются только для Java-интерфейсы.
Вы можете создать функцию расширения, чтобы сделать его работать, хотя:
// Assuming the type of dataManager is DataManager.
fun DataManager.createAndSubmitSendIt(title: String,
message: String,
progressListener: (Long) -> Unit) {
createAndSubmitSendIt(title, message,
object : ProgressListener {
override fun transferred(bytesUploaded: Long) {
progressListener(bytesUploaded)
}
})
}
Котлин поддерживает только преобразование Сэм для Java-интерфейсы.
... обратите внимание, что эта функция работает только для Java-взаимодействия; поскольку Котлин имеет правильную типы функций, автоматическое преобразование функции в реализаций интерфейсов Котлин является необязательным и поэтому не поддерживается.
Если вы хотите использовать лямбда-выражение в качестве параметра, делает свои функции принимают параметр функции, а не интерфейс. (По крайней мере сейчас. Поддержка преобразования Сэм для интерфейсов Котлин продолжается дискуссия, это был один из возможных будущих услуг в Котлин 1.1 прямую трансляцию.)
Немного опоздала на вечеринку: вместо того, чтобы делать интерфейс, вы позволите составить зделать с функцией напрямую, а не интерфейс в datamanager, как это:
fun createAndSubmitSendIt(title: String, message: String, transferred: (Long) -> Unit) {
val answer = TODO("whatever you need to do")
transferred(answer)
}
и тогда вы просто использовать его, как вы хотите его! Если я правильно помню, что Котлин/JVM и компилятора сделать то же самое, что интерфейс.
Надеюсь, что это помогает!
Другое решение могло бы заключаться в объявлении typealias, впрыскивая его куда-нибудь и воспользуюсь им. Вот пример:
internal typealias WhateverListener = (String) -> Unit
а потом вводят что typealias в нашем классе:
class Gallery constructor(private val whateverListener: WhateverListener) {
...
galleryItemClickListener.invoke("hello")
...
}
Итак, у нас есть лямда:
val gallery = Gallery { appNavigator.openVideoPlayer(it) }
Кредиты на моя коллега Джоэл Педраса, который показал мне трюк, пытаясь найти решение <3.
Нет единого окончательного решения этой проблемы, если вы хотите лучший опыт из обеих Котлин и Java.
Если разработчики Котлин не подумал преобразования Сэм для интерфейсов Котлин ненужно, то "Котлин интерфейс и" метод будет наилучшим решением.
https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions Также обратите внимание, что эта функция работает только для Java-взаимодействия; поскольку Котлин имеет правильную типы функций, автоматическое преобразование функции в реализаций интерфейсов Котлин является необязательным и поэтому не поддерживается.
Выберите лучшее решение для вашего случая.
Тип Функции Котлин #
- Котлин по API: идеальное
- Котлин Доступа: Идеальное
- Доступ К Java:
- Автоматически сгенерированный параметр типа функция function1 (не большая проблема для Java 8 лямбда)
- Блок возврата многословный`.Примеру; вместо возврата Void.
класс KotlinApi { забавные демо(слушателя: (ответ: строка) -> группа) { слушатель("в ответ на") } }
удовольствие kotlinConsumer() { KotlinApi().демо { успех -и GT; код println(успех) } }
javaConsumer общественного недействительными() { новый KotlinApi().демо(с -> { Системы.из.метод println(ы); блок возврата.Экземпляра; }); }
Интерфейс Котлин #
- Котлин API-интерфейс: дополнительный интерфейс определению.
- Котлин доступ: слишком многословно
- Доступ К Java: Идеальное
класс KotlinApi { интерфейс слушателя { удовольствие onResponse(ответ: строка) }
забавные демо(слушателя: слушатель) { слушателя.onResponse("в ответ на") } }
удовольствие kotlinConsumer() { KotlinApi().демо(объект : KotlinApi.Слушатель { переопределить удовольствие onResponse(ответ: строка) { метод println(ответ) } }) }
//Если Котлин поддерживает преобразование Сэм для интерфейсов Котлин. :( //весело kotlinConsumer() { // KotlinApi().демо { // код println(он) // } //}
javaConsumer общественного недействительными() { новый KotlinApi().демо(с -> { Системы.из.метод println(ы); }); }
Интерфейс Java #
- Котлин по API: смешанный код Java.
- Котлин доступа: немного многословный
- Доступ К Java: Идеальное
класс KotlinApi { забавные демо(слушателя: слушатель) { слушателя.onResponse("в ответ на") } }
слушатель публичного интерфейса { пустота onResponse(строку ответа); }
//Частичное преобразование Сэм удовольствие kotlinConsumer() { KotlinApi().демо(слушатель { код println(он) }) }
javaConsumer общественного недействительными() { новый KotlinApi().демо(с -> { Системы.из.метод println(ы); }); }
- Котлин API-интерфейса: несколько реализаций метода
- Котлин доступа: идеально, если использовать правильный метод. Автоматическое завершение предлагается подробный способ также.
- Доступ К Java: Идеальное. Автоматическое завершение не предполагает функцию метода типа потому что JvmSynthetic аннотации
класс KotlinApi { интерфейс слушателя { удовольствие onResponse(ответ: строка) }
забавные демо(слушателя: слушатель) { демо { слушателя.onResponse(он) } }
@JvmSynthetic //мешает JVM использовать этот метод забавные демо(слушателя: (строка) -> группа) { слушатель("в ответ на") } }
удовольствие kotlinConsumer() { KotlinApi().демо { код println(он) } }
javaConsumer общественного недействительными() { новый KotlinApi().демо(с -> { Системы.из.метод println(ы); }); }
- Котлин API-интерфейс: нет Котлин API, все код API на Java
- Котлин доступа: идеальное
- Доступ к Java: идеальное
открытый класс JavaApi { общественного недействительными демо(слушатель-слушатель) { слушателя.onResponse("в ответ" - а); }
слушатель публичного интерфейса { пустота onResponse(строку ответа); }
}
//Полного преобразования Сэм удовольствие kotlinConsumer() { JavaApi().демо { код println(он) } }
javaConsumer общественного недействительными() { новый JavaApi().демо(с -> { Системы.из.метод println(ы); }); }