2014-10-22 67 views
22

考慮以下Java類:Lambda表達式在科特林

public class SomeClass { 
    public interface Something { 
     void doSomething(); 
    } 

    public void call(Something something) {} 
} 

在科特林,我可以使用lambda表達式如下:

SomeClass().call { 
    // do something 
} 

但是,如果我定義科特林以下的方法(使用相同的接口):

fun call(something: Something) {} 

,則此調用:

call { 
    // do something 
} 

會生成類型不匹配錯誤。爲什麼?

回答

25

科特林只支持Java方法SAM的轉換,因爲科特林本身具有的功能類型。通常,Kotlin函數應該採用() -> Unit而不是Something。如果你真的需要它採取Something,您可以使用SAM構造:

call(Something { /* do something */ }) 

任何SAM型(帶一個抽象方法的Java接口)自動獲得,使得轉換一個lambda其實例的構造函數。

+4

這個決定對我來說很奇怪。考慮'List <(T) -> Unit>'vs'List >'。第二個則載有更多的信息。幸運的是有一個解決方法:我們可以在kotlin項目中自由使用java代碼。 – Yaroslav 2015-09-24 07:34:27

+0

雖然沒有太多的使用該解決方法:( – Yaroslav 2015-09-24 07:45:20

+3

命名函數類型是一個不同的故事,他們將在下一個版本的Kotlin支持 – 2015-09-24 17:41:07

8

Kotlin要求通話需要接口something

() -> Kotlin.Unit 

不滿足類型要求。

你可以做到這一點

call (object : Something { 
    override fun doSomething() { 
     println("Passing an interface to call in kotlin!") 
    } 
})