1. ホーム
  2. lambda

インターフェイスの代わりにラムダを渡す

2023-09-04 16:29:03

質問

あるインターフェースを作成しました。

interface ProgressListener {
    fun transferred(bytesUploaded: Long)
}

が、無名クラスとしてのみ使用可能で、ラムダではありません。

dataManager.createAndSubmitSendIt(title, message,
object : ProgressListener {
    override fun transferred(bytesUploaded: Long) {
        System.out.println(bytesUploaded.toString())
    }
})

lambdaで置き換えることも可能なはずです。

dataManager.createAndSubmitSendIt(title, message, {System.out.println(it.toString())})

しかし、エラーが発生します。 Type mismatch; required - ProgressListener, found - () -> Unit?

私は何を間違えているのでしょうか?

どうすればよいのでしょうか?

zsmb13 が言ったように、SAM 変換は Java インターフェースでのみサポートされています。

拡張関数を作って動作させることはできるけど。

// Assuming the type of dataManager is DataManager.
fun DataManager.createAndSubmitSendIt(title: String, 
                                      message: String, 
                                      progressListener: (Long) -> Unit) {
    createAndSubmitSendIt(title, message,
        object : ProgressListener {
            override fun transferred(bytesUploaded: Long) {
                progressListener(bytesUploaded)
            }
        })
}

編集する

Kotlin 1.4では、Kotlinで定義されたインターフェイスのSAM変換を可能にする関数インターフェイスが登場する予定です。つまり、インターフェイスを fun キーワードで定義すれば、ラムダで関数を呼び出せるということです。こんな感じ。

fun interface ProgressListener {
    fun transferred(bytesUploaded: Long)
}