Kotlin typealias与Android Room TypeConverters

Kotlin typealias与Android Room TypeConverters,kotlin,android-room,Kotlin,Android Room,我使用Kotlin的typealias定义了E164电话号码类型: typealias E164 = String 这使得我在代码中传递电话号码时的意图更加清晰,而不仅仅是传递字符串。我承认使用正确的类型并没有实际的强制执行,但这对我来说很有效 现在我想将E164存储在Android Room数据库中。这在不使用typealias的情况下可以工作,但使用typealias时需要一个TypeConverters。我试过这个: @Entity data class MyModel(@Primary

我使用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->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()
但是如果我没有定义类型转换器,那么编译器就不知道如何将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;

有人知道如何实现这一点吗?

您不需要
e164转换器。您可以将
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)
  }
}

对,但如果我将房间实体类中的一个属性从String更改为E164,然后,编译器告诉我需要提供一个类型转换器,因为它不知道如何将E164转换为可以放入数据库中的内容。向我展示完整的代码以及错误消息所指的位置。这应该是注释处理器在处理类型别名时的一个限制。让我为你想一个解决方案。看我的编辑。我使用
String
创建了构造函数,并将其设置为私有,然后使用
E164
创建了一个假构造函数。现在注释处理器将看到
String
,程序员将看到
E164
。看起来它应该可以工作了。没有我想要的那么优雅,但我看不到其他选择,谢谢。