Kotlin勉強してはまったこと

前置き

Webアプリもほんの少し作れるようになったので、
Androidアプリに手を出してみた。はじめてのKotlin。
落とし穴がいっぱい。これからも学習してみて、
嵌まってきたら定期的にこちらにアップしようと思う。
あと用語も間違えてるの気づいたらたまに修正する。

継承可能なクラスの作成

Kotlinで作成するクラスは、デフォルトで継承不可とのこと。
継承可能にするためにはopenモディファイアなるものをつける必要がある。

継承可能なクラスを作成する (open, abstract, override) | まくまくKotlinノート

下記のような感じ

// classの前にopenつけてる
open class TodoItem: RealmObject(){
    @PrimaryKey
    var id: Long = 0
    var dateTime: Date = Date()
    var todo: String = ""
}

Realm Databaseと一緒に使ったときに嵌まった。
上記コードはRealmのモデルクラスになるのだけれど
openつけないでビルドしたらなんか失敗した。
↓こんなエラー

Execution failed for task ':app:kaptDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
   > java.lang.reflect.InvocationTargetException (no error message)

エラーコードでググってもよくわかんなかったけど、
参考書のソースコードと比べてみてやっとopenつけなきゃいけないことに気づいた。

ビルド中にRealmモデルクラスを継承したJavaクラスを作ってる模様。
appname_TodoItemRealmProxy.javaみたいなクラスができてた。
自分で継承してなくて気づかなかった。

画面パーツにidつけ忘れた

たぶん写経くらいでしか嵌まることないんだけど。
下記のようなソースではまった。

class MainActivity : AppCompatActivity() {
    private lateinit var realm: Realm
    private lateinit var adapter: TodoRecyclerViewAdapter
    private lateinit var layoutManager: RecyclerView.LayoutManager

    override fun onStart() {
        super.onStart()
        realm = Realm.getDefaultInstance()
        val realmResults = realm.where(TodoItem::class.java)
            .findAll()
            .sort("id", Sort.DESCENDING)
        layoutManager = LinearLayoutManager(this)
        // このrecyclerViewではまった
        recyclerView.layoutManager = layoutManager

        adapter = TodoRecyclerViewAdapter(realmResults)
        recyclerView.adapter = this.adapter
    }
}

変数使うときKotlinではvarとかvalで宣言してるけど、
recyclerViewっていう変数は特に宣言してない。参考書の写経してて、
なんで宣言してない変数名があるんだ誤字脱字か?
と勝手に怒って小一時間くらい悩んだ。

結果、原因はactivity_main.xmlのidつけわすれ。
画面に表示するボタンとかレイアウトとかパーツごとに
idをつけといて、そのidでパーツ特定してKotlinで操作するのだけど、
そもそも「recyclerView」というidを該当のパーツにつけ忘れてた。

変数の宣言は全然関係なかった。参考書はすごく良書です。
ちゃんとidつけててbuild.gradle(:app)に

plugins {
    id 'kotlin-android-extensions'
}

って書いとけばAndroid Studioのコード補完に出てきてくれる。