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

时间:2013-04-20 13:04:07

标签: kotlin

给定函数foo:

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

我们可以这样做:

foo("a message", { println("this is a message: $it") } )
//or 
foo("a message")  { println("this is a message: $it") }

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

fun buz(m: String) {
   println("another message: $m")
}

有没有办法可以将“buz”作为参数传递给“foo”? 类似的东西:

foo("a message", buz)

11 个答案:

答案 0 :(得分:126)

使用::表示功能参考,然后:

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

Since Kotlin 1.1您现在可以使用属于类成员的函数(“绑定可调用引用”),方法是在函数引用运算符前面添加实例:

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

foo("hi", thatOtherThing::buz)

foo("hi", this::buz)

答案 1 :(得分:6)

关于成员函数作为参数:

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

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

答案 2 :(得分:2)

答案 3 :(得分:2)

只需在方法名称

之前使用“::”
fun foo(function: () -> (Unit)) {
   function()
}

fun bar() {
    println("Hello World")
}

foo(::bar) 输出Hello World

答案 4 :(得分:1)

Kotlin 1.1

使用::来引用方法。

    foo(::buz) // calling buz here

    fun buz() {
        println("i am called")
    }

答案 5 :(得分:0)

如果您想通过设置器获取器方法。

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

用法:

private var width: Int = 1

setData({ width = it }, { width })

答案 6 :(得分:0)

Jason Minard的答案很好。这也可以使用lambda来实现。

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

val buz = { m: String ->
    println("another message: $m")
}

可以用foo("a message", buz)来调用。

您还可以使用typealias使它更干燥。

typealias qux = (m: String) -> Unit

fun foo(m: String, bar: qux) {
    bar(m)
}

val buz: qux = { m ->
    println("another message: $m")
}

答案 7 :(得分:0)

另一个例子:

 fun foo(x:Int, Multiply: (Int) -> (Int)) {
    println(Multiply(x))
 }
 fun bar(x:Int):Int{
    return  x * x
 }
 foo(10, ::bar)

答案 8 :(得分:0)

如果这是您唯一使用该函数的地方,也可以使用lambda进行内联

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="36dp"
    android:height="36dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/black"
      android:pathData="M12,6v1.79c0,0.45 0.54,0.67 0.85,0.35l2.79,-2.79c0.2,-0.2 0.2,-0.51 0,-0.71l-2.79,-2.79c-0.31,-0.31 -0.85,-0.09 -0.85,0.36L12,4c-4.42,0 -8,3.58 -8,8 0,1.04 0.2,2.04 0.57,2.95 0.27,0.67 1.13,0.85 1.64,0.34 0.27,-0.27 0.38,-0.68 0.23,-1.04C6.15,13.56 6,12.79 6,12c0,-3.31 2.69,-6 6,-6zM17.79,8.71c-0.27,0.27 -0.38,0.69 -0.23,1.04 0.28,0.7 0.44,1.46 0.44,2.25 0,3.31 -2.69,6 -6,6v-1.79c0,-0.45 -0.54,-0.67 -0.85,-0.35l-2.79,2.79c-0.2,0.2 -0.2,0.51 0,0.71l2.79,2.79c0.31,0.31 0.85,0.09 0.85,-0.35L12,20c4.42,0 8,-3.58 8,-8 0,-1.04 -0.2,-2.04 -0.57,-2.95 -0.27,-0.67 -1.13,-0.85 -1.64,-0.34z"/>
</vector>

答案 9 :(得分:0)

这是一个简单的例子,我将乘法函数作为参数传递给另一个函数。

fun main(){
    result(10,3,::multiplication)// pass function as parameter wow kotlin amazing
}
fun multiplication(first:Int,second:Int):Int{
    return first*second
}
fun result(firstOne:Int,secondOne: Int,fn:(Int,Int)->Int){
    val result=fn(firstOne,secondOne)
    print(result)

}

答案 10 :(得分:-5)

Kotlin目前不支持一流的功能。关于这是否是一个很好的补充功能一直存在争议。我个人认为他们应该这样做。