我已经使用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()
但是,如果我没有定义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;
有人知道如何实现吗?
最佳答案
您不需要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)
}
}