Kotlin: как передать объектную функцию как параметр другому?

Я пытаюсь изучить функциональный Kotlin и написал этот тестовый код:

import java.util.* data class BorrowerX(val name: String, val maxBooks: Int) { companion object { fun getName(br: BorrowerX): String = br.name fun findBorrowerX(n: String, brs: ArrayList<BorrowerX>): BorrowerX? { val coll: List<BorrowerX> = brs.filter { BorrowerX.getName(it) == n } if (coll.isEmpty()) { return null } else return coll.first() } fun findBorrowerX2(n: String, brs: ArrayList<BorrowerX>, f: (BorrowerX) -> String): BorrowerX? { val coll: List<BorrowerX> = brs.filter { f(it) == n } if (coll.isEmpty()) { return null } else return coll.first() } } } 

В REPL я могу успешно вызвать «findBorrowerX»:

 import BorrowerX val br1 = BorrowerX(name = "Borrower1", maxBooks = 1) val br2 = BorrowerX(name = "Borrower2", maxBooks = 2) val br3 = BorrowerX(name = "Borrower3", maxBooks = 3) val brs1 = arrayListOf(br1, br2, br3) BorrowerX.findBorrowerX("Borrower1", brs1) BorrowerX(name=Borrower1, maxBooks=1) BorrowerX.findBorrowerX("Borrower-Bad", brs1) null 

Но как мне позвонить на «findBorrowerX2»:

 BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX.getName(???)) 

И передать итерированный BorrowerX getName?

Это выглядит связанным, но я не уверен:

Kotlin: как передать функцию как параметр другому?

Заранее благодарю вас за помощь!

РЕДАКТИРОВАТЬ:

Вот эквивалентный код Scala для того, что я хочу сделать:

 def findBorrowerX2(n: String, brs: List[BorrowerX], f: BorrowerX => String): BorrowerX = { val coll: List[BorrowerX] = brs.filter(f(_) == n) if (coll.isEmpty) { null } else { coll.head } } scala> BorrowerX.findBorrowerX2("Borrower3", brs1, BorrowerX.getName(_)) res1: BorrowerX = BorrowerX(Borrower3,3) scala> BorrowerX.findBorrowerX2("Borrower33", brs1, BorrowerX.getName(_)) res2: BorrowerX = null 

Возможно, это невозможно в Котлине?

Вы можете использовать :: operator для получения ссылки на функцию:

 BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX.Companion::getName) 

Здесь BorrowerX.Companion::getName – ссылка на функцию getName объявленную в сопутствующем объекте (с именем Companion ) класса BorrowerX . Он имеет тип KFunction1<BorrowerX, String> который является подтипом требуемого типа функциональных параметров (BorrowerX) -> String .

Стоит отметить, что вы можете использовать :: operator для получения ссылки на свойства:

 BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX::name) 

BorrowerX::name имеет тип KProperty1<BorrowerX, String> который также является подтипом (BorrowerX) -> String . При вызове с указанным экземпляром BorrowerX он возвращает значение свойства name .

Как указано в документации по лямбдам :

 BorrowerX.findBorrowerX2("Borrower-Bad", brs1, { it.name }) 

или когда лямбда является последним параметром метода:

 BorrowerX.findBorrowerX2("Borrower-Bad", brs1) { it.name } 

Типы типов и имена параметров явно часто улучшают читаемость:

 BorrowerX.findBorrowerX2("Borrower-Bad", brs1) { borrower:BorrowerX -> borrower.name } 
Intereting Posts
Каковы преимущества сопутствующего объекта над простым объектом? re enable intellij java to kotlin conversion Есть ли в Kotlin аналог didSet / willSet? Связанная ссылка на вызов не работает с реактором Подписаться Ссылка на представления с одним и тем же идентификатором в разных макетах с расширением android kotlin Proguard: Какое правило я могу добавить во избежание, не может найти ссылочный класс? Соглашение о кодировании для пустых функций, которые необходимо переопределить в Котлине Различные вопросы @NonNull, @NotNull и @ParametersAreNonnullByDefault Статус ответа HTTP SpringBoot Kotlin Api Kotlin – любая замена сопутствующего объекта внутри другого объекта (не класса)? В Котлине не работает почтовая служба, что не так Связывание слушателя; Не удается найти сеттер Лучший способ повторить JSON в Котлине Зипкин зигзага не может гнездиться в котине Фильтрация данных из коллекции с определенной строкой