我使用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;
有谁知道如何实现这个?
答案 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)
}
}