Android Architecture ComponentsのRoomでは、直接SQLiteに格納できない型を格納する場合、変換するためのTypeConverterを実装してEntityやDaoなどで指定する必要があります。
TypeConverter | Android Developers
変換するためのメソッドに@TypeConverter
アノテーションを付加するのですが、このアノテーションのドキュメントにはこう書いています。
Each converter method should receive 1 parameter and have non-void return type.
変換対象を唯一のパラメータとして受け取り、void以外の型を返せばいいようです。
拡張関数で書かれた関数をjavaにデコンパイルしたものを見たことがある方ならご存知かもですが、Kotlinの拡張関数はJavaから見ると拡張元の型を第1引数に持つメソッドになります。
class Sample {
fun List<Int>.doubleSize() = this.size * 2
}
例えば、上記の拡張関数をデコンパイルすると
public final class Sample {
public final int doubleSize(@NotNull List $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver.size() * 2;
}
}
のようになります。
したがって、TypeConverterをKotlinで書く際は次のように拡張関数で書くことが可能です。
class ListTypeConverter {
@TypeConverter
fun List<Int>.toCsvString(): String = joinToString(",")
@TypeConverter
fun String.toIntList(): List<Int> = split(",").map { it.toInt() }
}
クラスではなくobjectにしたい場合は一工夫 -> @JvmStatic
が必要
object ListTypeConverter {
@TypeConverter
@JvmStatic
fun List<Int>.toCsvString(): String = joinToString(",")
@TypeConverter
@JvmStatic
fun String.toIntList(): List<Int> = split(",").map { it.toInt() }
}
おまけ
カラムをnullableにしてたの忘れててクラッシュしたので修正。
— ちばっちんぐ (@chibatching) March 10, 2018
ほとんど変わってないのはKotlin様〜って感じ pic.twitter.com/XTWU1Zz8Fq