Kotlin typealias с Android Тип комнаты Конвертеры - PullRequest
0 голосов
/ 25 апреля 2018

Я использовал typealias Kotlin для определения типа телефонного номера 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
}

Компилятору не нравится автоматически сгенерированный Java класса E164Converters, потому что методы 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;

Кто-нибудь знает, как это реализовать?

1 Ответ

0 голосов
/ 25 апреля 2018

Вам не нужно 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)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...