使用Android Room TypeConverters的Kotlin typealias

时间:2018-04-25 05:51:43

标签: kotlin android-room

我使用Kotlin的typealias来定义E164电话号码类型:

typealias E164 = String

在我的代码中传递电话号码时,这使我的意图更加清晰,而不仅仅是传递字符串。我认识到没有使用正确类型的实际强制执行,但这对我很有用。

现在我想将E164存储在Android Room数据库中。这可以在没有typealias的情况下工作,但是对于typealias它需要TypeConverters。我试过这个:

@Entity data class MyModel(@PrimaryKey val e164: E164, val someOtherThing: String)

class E164Converters {
    @TypeConverter
    fun toE164(value: String): E164 = value

    @TypeConverter
    fun toString(e164: E164): String = e164
}

编译器不喜欢E164Converters类的自动生成的Java,因为toString和toE164方法都定义了相同的String转换 - >串。

error: Multiple methods define the same conversion. Conflicts with these: CustomTypeConverter(type=E164Converters, method=toString(java.lang.String), from=java.lang.String, to=java.lang.String) public final java.lang.String toE164(@org.jetbrains.annotations.NotNull()

但如果我没有定义TypeConverters,那么编译器不知道如何将E164放入数据库中:

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private final error.NonExistentClass e164 = null;

有谁知道如何实现这个?

1 个答案:

答案 0 :(得分:2)

您不需要E164Converters。您可以将E164用作String。像

val a: E164 = "blabla"

fun f(x: String) = x
f(a) // compiles

我想你正在编写像

这样的东西
fun processPhoneNumber(a: E164) {
  // blabla
}

您可以像processPhoneNumber("110")一样调用上面的函数,它可以正常工作。

你说在

中使用它时会出错
@Entity data class MyModel(
  @PrimaryKey val e164: E164,
  val someOtherThing: String
)

如果我是你,我可以考虑用以下代码替换上面的代码:

data class MyModel private constructor(
  @PrimaryKey val e164: String,
  val someOtherThing: String
) {
  companion object {
    operator fun invoke(e164: E164, someOtherThing: String) =
      MyModel(e164, someOtherThing)
  }
}