LoginSignup
4
2

More than 5 years have passed since last update.

KotlinでSAM(Single Abstract Method)インターフェースを作ったら省略記法が使えなかった話

Posted at

問題

JavaでInterface定義し、抽象メソッドが一つだけのもの(Single Abstract Method: SAM)をKotlinで呼び出すときは下記みたいな感じでいける

view.setOnClickListener { view ->
  // something
}

一方、下記のようにKotlinでSAMのInterfaceを作っても同じように呼び出せない

  • 呼ばれる側
interface HogeListener {
    fun fuga(s: String)
}

setHogeListener(listener: HogeListener) {
    this.listener = listener
}
  • 呼ぶ側
hogehoge.setHogeListener { s ->

} 
// ERROR: 
//   Type Mismatch.
//   Required: A.HogeListener
//   Found: (???) -> Unit
//   Cannot infer a type for this parameter. Please specify it explicitly.

原因

Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.

JavaのSAMはよしなに変換してくれるけど、Kotlinは必要ないから変換しないとのこと。

対応

とりあえずJavaの時と使い勝手を変えたくなかったので下記のように実装。

class Hoge(private var listener: (String) -> Unit) {
    fun fuga(string: String) {
        listener(string)
    }
}

setHogeListener(listener: (String)->Unit) {
    listener = Hoge(listener)
}

実際にはKotlin化と同時に不要なインターフェースを無くしていくのがベストなんだろなぁと思いつつ、一時対応としてメモ。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2