我正在尝试学习功能性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中,我可以成功调用&#34; findBorrowerX&#34;:
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
但是如何调用&#34; findBorrowerX2&#34;:
BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX.getName(???))
并将迭代的BorrowerX传递给getName ??
这看起来很相关,但我不确定:
Kotlin: how to pass a function as parameter to another?
提前感谢您的帮助!
编辑:
以下是我想要做的等效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
也许这在Kotlin中是不可能的?
答案 0 :(得分:2)
您可以使用::
运算符来获取函数引用:
BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX.Companion::getName)
此处BorrowerX.Companion::getName
是对类getName
的伴随对象(名为Companion
)中声明的函数BorrowerX
的引用。它的类型为KFunction1<BorrowerX, String>
,它是所需功能参数类型(BorrowerX) -> String
的子类型。
值得注意的是,您也可以使用::
运算符来获取属性引用:
BorrowerX.findBorrowerX2("Borrower1", brs1, BorrowerX::name)
BorrowerX::name
的类型KProperty1<BorrowerX, String>
也是(BorrowerX) -> String
的子类型。使用指定的BorrowerX
实例调用时,它将返回其name
属性的值。
答案 1 :(得分:0)
如the documentation on lambdas中所述:
BorrowerX.findBorrowerX2("Borrower-Bad", brs1, { it.name })
或当lambda是方法的最后一个参数时:
BorrowerX.findBorrowerX2("Borrower-Bad", brs1) { it.name }
明确说明类型和参数名称通常会提高可读性:
BorrowerX.findBorrowerX2("Borrower-Bad", brs1) { borrower:BorrowerX -> borrower.name }