2013-04-20 88 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(如果不同)

相關問題