経緯
俺「Javaを使っていたけど、これからはKotlinだ! まずは TextView での文字列の表示のあたりから。」
俺「textView.setText("文字列") っと。ほとんどJavaと変わらないけど、セミコロンが不要になったのはいいな」
Android Studio「セッターメソッドの呼び出しをプロパティ構文に置き換えられるよ!」
俺「なるほど!プロパティ構文で書けるのか、textView.text = "文字列" っと。いいね!」
俺「さて、じゃあ TextView の派生クラスである EditText の方も書き換えよう。 editText.text = "文字列" っと」
Kotlin「Type mismatch: inferred type is String but Editable! was expected」
俺「え?」
Kotlin「Editableじゃないとダメです。String なら setText() を使って。」
俺「...」
理由
TextView#getText() の戻り値の型は CharSequence 1 だが、
EditText#getText() の戻り値の型は Editable 2 となっているため。
どういうことか
なぜセッター(setText())ではなく、ゲッター(getText())の話が出てきたかというと
Javaで定義されたゲッター/セッターをKotlinからプロパティ構文でアクセスする際、型の推論にはゲッターの戻り値の型が使用されるため。
(ちなみに、セッターしか無く対応するゲッターが無い場合にはプロパティ構文すら使えない)
メソッドのオーバーライド時に、戻り値の型を派生型(Editable は CharSequence の派生型)に変えることは許されているので、こんな事態となってしまっている模様。
(´・ω・`)
それでもプロパティ構文が使いたい
TextView に明示的にキャストする
(editText as TextView).text = "文字列"
基底クラスにキャストするという一見「?」なコードにはなってしまう。
(別) Editable に変換する
editText.text = Editable.Factory.getInstance().newEditable("文字列")
インスタンス生成を伴うのでパフォーマンスが重視される場面では注意。