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】:如果你想传递 setter 和 getter 方法。
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函数作为参数传递给另一个函数