首页 文章

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

提问于
浏览
0

我正在尝试学习功能性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: 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

也许这在科特林是不可能的?

2 回答

  • 0

    您可以使用 :: 运算符来获取函数引用:

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

    这里 BorrowerX.Companion::getName 是对类 BorrowerX 的伴随对象(名为 Companion )中声明的函数 getName 的引用 . 它的类型为 KFunction1<BorrowerX, String> ,它是所需功能参数类型 (BorrowerX) -> String 的子类型 .

    值得注意的是,您也可以使用 :: 运算符来获取属性引用:

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

    BorrowerX::name 的类型为 KProperty1<BorrowerX, String> ,它也是 (BorrowerX) -> String 的子类型 . 当使用指定的 BorrowerX 实例调用时,它返回其 name 属性的值 .

  • 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 }
    

相关问题