gpt4 book ai didi

android - 如何将扩展函数用作 Room 数据库的 TypeConverter 方法?

转载 作者:行者123 更新时间:2023-11-29 00:55:42 26 4
gpt4 key购买 nike

我想知道是否有人找到了在使用 Room 数据库时将 kotlins 扩展函数用作 TypeConverter 方法的方法。代码看起来非常干净,但我一直无法找到将转换器添加到 RoomDatabase 转换器数组的方法:

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")
}
}

即使测试看起来也 super 优雅:

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 的扩展。我已经编辑了我的问题以显示这一点。

最佳答案

首先,其中一种扩展方法 (fromInt()) 不是真正的转换器方法。对于该方法,Room 需要一个(在 java 中)形式的方法:

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

但是 Kotlin 编译器会生成(在 java 中)类似的东西

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

Room 不知道如何处理这个方法,它需要将数据库中的 int 转换为您的 Status 字段。

其次,在目前的形式下,这两种扩展方法毫无用处。一个是 Status.ACTIVE.code 的别名,另一个将简单地返回被调用的实例。

您不能将这些方法用于 TypeConverters 接口(interface),因为该接口(interface)需要一个将所需静态方法分组的类引用。您无法在 kotlin 中访问将由 kotlin 编译器生成的 java 类(包含方法),因此您无法在数据库上使用它。

如果您想保留当前的扩展方法,但也想创建所需的类型转换器方法,您可以使用如下的一些间接方法:

fun Status.toInt(): Int = StatusConverters.toInt(this)

fun Status.fromInt(): Status = StatusConverters.fromInt(this.code)

object StatusConverters {
@TypeConverter
@JvmStatic
fun toInt(status: Status): Int = status.code // This could be shorter I know

@TypeConverter
@JvmStatic
fun fromInt(code: Int): Status = when (code) { // 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")
}
}
}

关于android - 如何将扩展函数用作 Room 数据库的 TypeConverter 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54922914/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com