Как создать объект в Kotlin с помощью конструктора, который принимает общий интерфейс и другие параметры

Я использую AssertJ в Kotlin и пытался использовать AssertJ-Condition.

Конструктор определяется следующим образом:

Condition(Predicate<T> predicate, String description, Object... args)

См. http://joel-costigliola.github.io/assertj/core-8/api/org/assertj/core/api/Condition.html

Но я не могу получить правильное творение. Я попробовал следующее (и еще несколько, которые я пропустил для краткости):

Condition<File>({ it.name.startsWith("functional_questions") }, "Description")

с этой ошибкой: введите здесь описание изображения

Condition<File>({ file -> file.name.startsWith("functional_questions") }, "Description")

с этой ошибкой: введите здесь описание изображения

Как я могу добиться успеха?


person Nils-o-mat    schedule 18.07.2018    source источник
comment
что произойдет, если вы используете { file: File -> ... } ?   -  person crgarridos    schedule 18.07.2018
comment
Так же, как это все еще (File) -> Boolean, а не Predicate<File>   -  person avolkmann    schedule 18.07.2018


Ответы (2)


Лучшее, что я могу придумать, это:

Condition<File>(Predicate<File> { file -> file.name.startsWith("functional_questions") }, "description")

Изменить: ваш код не работает, потому что лямбда Kotlin по умолчанию не реализует требуемый интерфейс. Если вы запустите следующий код:

val predicate1 = { file: File -> file.name.startsWith("functional_questions") }
val predicate2 = Predicate<File> { file -> file.name.startsWith("functional_questions") }

predicate1::class.java.interfaces.forEach { println(it) }
println() //new line to separate outputs
predicate2::class.java.interfaces.forEach { println(it) }

вы получите следующий вывод:

interface kotlin.jvm.functions.Function1

interface java.util.function.Predicate

Разница очевидна.

person Konrad Botor    schedule 18.07.2018
comment
Спасибо, это работает. Но я действительно не понимаю, почему приведенный выше код не работает. - person Nils-o-mat; 18.07.2018
comment
В качестве улучшения кода я бы рекомендовал использовать it или говорящий дескриптор, например file. - person Nils-o-mat; 18.07.2018
comment
Спасибо за совет, смотрите мое редактирование для получения дополнительной информации. - person Konrad Botor; 18.07.2018

Насколько я вижу, AssertJ не имеет специальной поддержки Kotlin, поэтому поддерживается только предикат Java.

Подробнее о том, почему мы не можем передавать kotlin lambdas в качестве функциональных интерфейсов, см. здесь: https://stackoverflow.com/a/33610615/5335131

Вот два способа заставить его работать:

@Test fun assertj() {
    Condition<File>(Predicate { it.name.startsWith("functional_questions") }, "Description")
    condition<File>("Description") { it.name.startsWith("functional_questions") }
}

fun <T> condition(description: String, predicate: (T) -> Boolean) =
    Condition<T>(Predicate<T> { predicate(it) }, description)

Сначала с явным предикатом, а затем с помощником.

person avolkmann    schedule 18.07.2018