Kotlin:如何将对象函数作为参数传递给另一个?

时间:2016-10-10 00:34:52

标签: 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中,我可以成功调用&#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中是不可能的?

2 个答案:

答案 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 }