Как использовать функции расширения в качестве методов TypeConverter для базы данных Room? - PullRequest
0 голосов
/ 28 февраля 2019

Мне было интересно, нашел ли кто-нибудь способ использовать функции расширения kotlins как TypeConverter методы при использовании базы данных Room.Код выглядит супер чистым, но я не смог найти способ добавить конвертер в массив RoomDatabase s конвертеров:

enum class Status(val code: Int) {
    ACTIVE(0), INACTIVE(1), COMPLETED(2)
}

@TypeConverter
fun Status.toInt() : Int = this.code // This could be shorter I know

@TypeConverter
fun Int.toStatus() : Status = when(this) { // This could also be shorter
    Status.ACTIVE.code -> Status.ACTIVE
    Status.INACTIVE.code -> Status.INACTIVE
    Status.COMPLETED.code -> Status.COMPLETED
    else -> {
        Timber.e("Could not recognize Status")
        throw IllegalArgumentException("Could not recognize Status")
    }
}

Даже тесты выглядят очень элегантно:

class SampleConverterTest {

    @Test
    fun fromIntToActiveStatus() {
        assertThat(Status.ACTIVE.toInt(), `is`(Status.ACTIVE.code))
    }

    @Test
    fun fromIntToInactiveStatus() {
        assertThat(Status.INACTIVE.toInt(), `is`(Status.INACTIVE.code))
    }

    @Test
    fun fromIntToCompletedStatus() {
        assertThat(Status.COMPLETED.toInt(), `is`(Status.COMPLETED.code))
    }

    @Test
    fun fromActiveStatusToInt() {
        assertThat(Status.ACTIVE.fromInt(), `is`(Status.ACTIVE))
    }

    @Test
    fun fromInactiveStatusToInt() {
        assertThat(Status.INACTIVE.fromInt(), `is`(Status.INACTIVE))
    }

    @Test
    fun fromCompletedStatusToInt() {
        assertThat(Status.COMPLETED.fromInt(), `is`(Status.COMPLETED))
    }
}

Я не очень знаком с java kotlin interop, но есть ли способ использовать эти расширения как ваши TypeConverters?

РЕДАКТИРОВАТЬ:

Остерегайтесь, как @Luksprog указал в своем ответе, метод расширения Status.fromInt() не является правильным методом конвертера.Вместо этого это должно быть расширение на Int.Я отредактировал свой вопрос, чтобы показать это.

1 Ответ

0 голосов
/ 28 февраля 2019

Прежде всего, один из методов расширения (fromInt ()) не является настоящим методом конвертера.Для этого метода Room ожидает метод в виде (в java):

static Status fromInt(int code){...}

, однако компилятор Kotlin сгенерирует (в java) что-то вроде

static Status fromInt(Status obj){...}

Room не будет знатьчто делать с этим методом, который нужно преобразовать из int в базе данных в ваше поле Status.

Во-вторых, в их текущей форме эти два метода расширения довольно бесполезны.Один из них является псевдонимом для Status.ACTIVE.code, а другой просто возвращает экземпляр, для которого вызывается.

Вы не можете использовать эти методы для интерфейса TypeConverters, поскольку этот интерфейс ожидает ссылку на класс, который группирует требуемую статическую переменную.методы.В kotlin вы не можете получить доступ к java-классу (содержащему методы), который будет сгенерирован компилятором kotlin, поэтому вы не можете использовать его в базе данных.

Если вы хотите сохранить текущие методы расширения, нотакже создайте необходимые методы преобразователей типов, которые вы могли бы использовать по некоторой косвенности, как показано ниже:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...