Почему автор определяет поля таблицы в двух позициях в комнате с Android Jetpack? - PullRequest
6 голосов
/ 02 марта 2020

Я учусь 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
}

Ответы [ 2 ]

4 голосов
/ 04 марта 2020

Объявление свойства внутри конструктора класса 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. Создание копий объекта, исключая указанные c поля
  2. Исключить указанные c поля для сравнения двух объектов с равными
  3. Исключить указанные c поля в объявлениях деструктурирования

Примечание: методы copy и component не могут быть предоставлены явно (внутри класса данных). В примере B gardenPlantingId заменено на id, поэтому может быть удалено.

2 голосов
/ 04 марта 2020

Ответ очень прост:

Поскольку в этом примере кода автор хочет показать, что мы можем использовать аннотации @PrimaryKey и @ColumnInfo для ЛЮБОГО члена внутри Класс сущности, независимо от его положения (он может быть внутри конструктора или снаружи).

Чтобы поэкспериментировать с этим, вы можете просто сделать то же, что и на Код B . Это также допустимо, но в этом случае gardenPlantingId не будет иметь пользовательского имени столбца, потому что мы не используем аннотацию @ColumnInfo. Кроме того, нет необходимости объявлять @PrimaryKey вне конструктора (как в данном примере). Вы можете просто объявить аннотацию первичного ключа внутри конструктора.

...