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

mhs*_*ams 112 kotlin

给定函数foo:

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}
Run Code Online (Sandbox Code Playgroud)

我们可以做的:

foo("a message", { println("this is a message: $it") } )
//or 
foo("a message")  { println("this is a message: $it") }
Run Code Online (Sandbox Code Playgroud)

现在,假设我们有以下功能:

fun buz(m: String) {
   println("another message: $m")
}
Run Code Online (Sandbox Code Playgroud)

有没有办法可以将"buz"作为参数传递给"foo"?就像是:

foo("a message", buz)
Run Code Online (Sandbox Code Playgroud)

Jay*_*ard 157

使用::以表示一个函数引用,然后:

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

// my function to pass into the other
fun buz(m: String) {
    println("another message: $m")
}

// someone passing buz into foo
fun something() {
    foo("hi", ::buz)
}
Run Code Online (Sandbox Code Playgroud)

从Kotlin 1.1开始,您现在可以通过在函数引用运算符前面添加实例来使用类成员函数(" 绑定可调用引用 "):

foo("hi", OtherClass()::buz)

foo("hi", thatOtherThing::buz)

foo("hi", this::buz)
Run Code Online (Sandbox Code Playgroud)

  • 可以传递成员引用,但在这种情况下,这将是一个2参数函数,第一个参数需要类的实例.更好的方法是使用在类上关闭的lambda包装成员函数.假设以上所有内容都在一个类中:`fun something(){foo("hi",{buz(it)})}` (7认同)
  • 如果我错了,请纠正我,但似乎只有顶级函数(即不属于类)才能以这种方式传递;类方法不能:-( (2认同)
  • 如果您在同一个类中操作,似乎可以传入属于一个类的函数,从 kotlin 1.1 开始,您可以使用 `this::function` 来实现 (2认同)

erl*_*man 11

只需在方法名称前使用“::”

fun foo(function: () -> (Unit)) {
   function()
}

fun bar() {
    println("Hello World")
}
Run Code Online (Sandbox Code Playgroud)

foo(::bar) 输出Hello World


Rui*_*hou 9

关于成员函数作为参数:

  1. Kotlin类不支持静态成员函数,因此不能像以下那样调用成员函数:Operator :: add(5,4)
  2. 因此,成员函数不能与First-class函数一样使用.
  3. 一个有用的方法是用lambda包装函数.它不优雅,但至少它是有效的.

码:

class Operator {
    fun add(a: Int, b: Int) = a + b
    fun inc(a: Int) = a + 1
}

fun calc(a: Int, b: Int, opr: (Int, Int) -> Int) = opr(a, b)
fun calc(a: Int, opr: (Int) -> Int) = opr(a)

fun main(args: Array<String>) {
    calc(1, 2, { a, b -> Operator().add(a, b) })
    calc(1, { Operator().inc(it) })
}
Run Code Online (Sandbox Code Playgroud)

  • 在目前的Kotlin中,您现在可以*使用成员函数作为参考.您现在应该更新此答案. (3认同)

Con*_*oid 7

科特林 1.1

用于::参考方法。

喜欢

    foo(::buz) // calling buz here

    fun buz() {
        println("i am called")
    }
Run Code Online (Sandbox Code Playgroud)


Coo*_*ind 7

如果你想传递settergetter方法。

private fun setData(setValue: (Int) -> Unit, getValue: () -> (Int)) {
    val oldValue = getValue()
    val newValue = oldValue * 2
    setValue(newValue)
}
Run Code Online (Sandbox Code Playgroud)

用法:

private var width: Int = 1

setData({ width = it }, { width })
Run Code Online (Sandbox Code Playgroud)