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

Posted

技术标签:

【中文标题】Kotlin:如何将一个函数作为参数传递给另一个函数?【英文标题】:Kotlin: how to pass a function as parameter to another? 【发布时间】:2013-04-13 19:06:03 【问题描述】:

给定函数 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)

【问题讨论】:

【参考方案1】:

使用:: 表示函数引用,然后:

fun foo(msg: String, bar: (input: String) -> Unit) 
    bar(msg)


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


// someone passing buz into foo
fun something() 
    foo("hi", ::buz)

Since Kotlin 1.1 您现在可以使用作为类成员的函数(“Bound Callable References”),方法是在函数引用运算符前面加上实例:

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

foo("hi", thatOtherThing::buz)

foo("hi", this::buz)

【讨论】:

如果我错了,请纠正我,但似乎只能以这种方式传递***函数(即不属于某个类);类方法不能:-( 可以传递成员引用,但在这种情况下,这将是一个 2 参数函数,第一个参数需要类的实例。更好的方法是用关闭类的 lambda 包装成员函数。假设以上所有内容都在一个类中:fun something() foo("hi", buz(it) ) 如果您在同一个类中操作,似乎可以传入属于某个类的函数,从 kotlin 1.1 开始,您可以使用 this::function 另外,如果你想让函数参数可以为空,只需将类型声明用括号括起来,最后加上一个问号。例如bar: ((m: String) -> Unit)? @MartyMiller 他们不是。参数m为foo,另一个参数是变量bar中传递给函数的函数类型的参数名。【参考方案2】:

关于成员函数作为参数:

    Kotlin 类不支持静态成员函数,因此不能像这样调用成员函数: 运算符::add(5, 4) 因此,成员函数不能与 First-class 函数一样使用。 一种有用的方法是用 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) )

【讨论】:

在当前的 Kotlin 中,您现在可以使用成员函数作为引用。您现在应该更新此答案。 通过在伴生对象中定义函数,调用代码变得更好,并且每次都不会创建新的 Operator 实例。这看起来像是 Java 中的静态乐趣 很好的解决方案,这是我发现当函数在类中时唯一有效的方法。我不认为它丑陋但美丽,几乎看起来像一个角度模板变量但用于代码。【参考方案3】:

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

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


fun bar() 
    println("Hello World")

foo(::bar) 输出 : Hello World

【讨论】:

此代码无法编译。 “function()”需要一个参数【参考方案4】:

科特林 1.1

使用:: 引用方法。

喜欢

    foo(::buz) // calling buz here

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

【讨论】:

【参考方案5】:

如果你想传递 settergetter 方法。

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】:

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】:

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

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)


【讨论】:

【参考方案8】:

显然这还不支持。

更多信息:

http://devnet.jetbrains.com/message/5485180#5485180

http://youtrack.jetbrains.com/issue/KT-1183

【讨论】:

这已被添加到 Kotlin,因此这个答案现在不正确。【参考方案9】:

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

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


foo("a message") 
    m: String -> println("another message: $m")

//Outputs: another message: a message

【讨论】:

【参考方案10】:

另一个例子:

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

【讨论】:

【参考方案11】:

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

【讨论】:

以上是关于Kotlin:如何将一个函数作为参数传递给另一个函数?的主要内容,如果未能解决你的问题,请参考以下文章

QML:如何将javascript函数作为参数传递给另一个函数

如何将带有 args 的成员函数作为参数传递给另一个成员函数?

将一个函数的多个返回值作为参数传递给另一个函数

C ++,将对象作为参数传递给另一个对象构造函数

如何将数组作为参数传递给另一个脚本?

将取消引用的指针作为函数参数传递给结构