首页 > 解决方案 > 为什么作者在 Room with Android Jetpack 的两个位置定义表格字段?

问题描述

我正在学习 Android Jetpack,以下代码来自https://github.com/android/sunflower的示例项目。

GardenPlanting.kt代码是设计一个表格,我很奇怪作者为什么在两个位置定义表格字段,你看 @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id")是位于类的内部。

我认为代码 B 很容易理解,对吧?

GardenPlanting.kt

@Entity(
    tableName = "garden_plantings",
    foreignKeys = [
        ForeignKey(entity = Plant::class, parentColumns = ["id"], childColumns = ["plant_id"])
    ],
    indices = [Index("plant_id")]
)

data class GardenPlanting(
    @ColumnInfo(name = "plant_id") val plantId: String,

    @ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),    

    @ColumnInfo(name = "last_watering_date")
    val lastWateringDate: Calendar = Calendar.getInstance()
) {
        @PrimaryKey(autoGenerate = true)
        @ColumnInfo(name = "id")
        var gardenPlantingId: Long = 0
}

代码 B

data class GardenPlanting(
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id")  val id: String,

    @ColumnInfo(name = "plant_id") val plantId: String,

    @ColumnInfo(name = "plant_date") val plantDate: Calendar = Calendar.getInstance(),

    @ColumnInfo(name = "last_watering_date")
    val lastWateringDate: Calendar = Calendar.getInstance()
) {

        var gardenPlantingId: Long = 0
}

标签: androidandroid-roomandroid-jetpack

解决方案


类构造函数中的属性声明data用于:

  1. 生成用于破坏的组件函数
  2. toString()在、equals()hashCode()和中使用这些字段copy()

因此,如果您想避免使用该copy方法复制字段,那么简单的方法是在类的主体内声明字段。

例子:

fun main() {
    val user = User("Pavneet", "29k+")
    user.id = kotlin.random.Random.nextInt(10, 20)
    val userCopy = user.copy()
    println(userCopy) // id won't be printed 'cuz it's not a part of toString method
    userCopy.id = 99
    print(userCopy.equals(user)) // true, 'cuz id is not being used by the equals method
    //var(name, repo, id) = userCopy // error, User must have a 'component3()' function
    var(name, repo) = userCopy

}

data class User(val name: String = "", val repo:String="0"){
    var id:Int = 0
}

好处:

  1. 创建不包括特定字段的对象副本
  2. 排除特定字段以比较两个对象是否相等
  3. 在解构声明中排除特定字段

注意:copycomponent方法不能显式提供(在数据类中)。在示例 B 中,gardenPlantingId被替换为idso 可以被移除。


推荐阅读