2013-04-20 89 views
43

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

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) 

回答

52

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

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您现在可以使用的类成员函数( “Bound Callable References“),通过与实例前缀功能参考操作:

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

foo("hi", thatOtherThing::buz) 

foo("hi", this::buz) 
+1

请纠正我,如果我错了,但似乎只有顶级功能(即不属于一类)可以通过这种方式传递;类方法不能: - ( – 2015-12-02 20:19:45

+5

)成员引用可以传递,但在这种情况下,这将是一个2参数函数,第一个参数需要类的一个实例。更好的方法是用lambda包装成员函数假设上面所有的都是在一个类中: 'fun something(){foo(“hi”,{buz(it)})}' – 2015-12-25 14:31:23

+0

是否有这样做,如果buz是通用的类型推断失败了吗? – 2016-08-18 21:45:57

-3

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

+1

第一类功能已经在kotlin中支持 – mhshams 2013-04-21 03:24:57

+0

这已过时,不正确。 – 2015-10-28 22:44:33

4

关于成员函数的参数:

  1. 科特林类不支持静态成员函数,所以成员函数可以” t被调用如: 运算符:: 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) }) 
} 
+3

在当前的Kotlin中,你现在*可以*使用成员函数作为参考。现在你应该更新这个答案。 – 2017-04-16 14:19:11

+0

通过定义伴随对象调用代码中的函数获得更好的一点,并且没有新的实例的操作符每次都会被创建。这看起来像Java中的静态乐趣 – 2018-02-20 04:36:35

0

就在方法名前使用 “::” 作为参数

fun main(args: Array<String>) { 
    runAFunc(::runLines) 
} 


fun runAFunc(predicate: (Int) -> (Unit)) { 
    val a = "five" 
    if (a == "five") predicate.invoke(5) else predicate.invoke(3) 

} 

fun runLines(numbers: Int) { 
    var i = numbers 
    while (i > 0) { 
     println("printed number is $i") 
     i-- 
    } 
} 
0

科特林1.1

此:: BUZ(如果在相同的类别)或类别():: buz(如果不同)

相关问题