Как разместить разные аргументы для класса сущности

Я вызываю свой класс сущности в операторе if/else-if для двух разных условий, и значения, которые я передаю в параметры, зависят от условия. В блоке if я передаю 3 параметра, а в блоке else-if я передаю 4. Объект объекта выдает ошибку, потому что он ожидает 4 параметра. Я хочу, чтобы первый параметр был необязательным, и я хотел бы знать, есть ли способ сделать это в Котлине.

Это мой класс сущности:

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    var id: Int? = null, 

    val username: String? = null, 
    val hint: String? = null, 
    val password: String? = null)

А это блок if/else-if, где я вставляю значения в объект сущности:

if (requestCode == ADD_ENTRY_REQUEST && resultCode == Activity.RESULT_OK) {
            ...

            val entry = Entry(username, hint, password)
            ...

        } else if (requestCode == EDIT_ENTRY_REQUEST && resultCode == Activity.RESULT_OK) {
            ...

            val entry = Entry(id, username, hint, password)
            ...

        }

В Java вы можете решить эту проблему, создав 2 конструктора с одинаковым количеством параметров, но мне интересно, можем ли мы сделать то же самое в Kotlin или есть другой подход.

1
0
59
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете попробовать переместить идентификатор в конец, например:

@Entity(tableName = "entry_table")
data class Entry(
    val username: String? = null, 
    val hint: String? = null, 
    val password: String? = null,
    @PrimaryKey(autoGenerate = true) 
    var id: Int? = null)

А затем создать его как:

val entry = Entry(username, hint, password, id)

Или, если вы хотите сохранить идентификатор в качестве первого параметра, вы можете использовать именованные аргументы следующим образом:

val entry = Entry(username = username, hint = hint, password = password)

Надеюсь, это поможет!

Вы можете и, вероятно, должны использовать несколько конструкторов.

Недостатком вашего подхода является то, что все свойства должны быть необязательными по техническим причинам. Но я думаю, username и password на самом деле обязательны. Последствиями являются потеря проверок времени компиляции (и, следовательно, склонность к NPE) и громоздкое чтение (!! необходимо при доступе к имени пользователя).

Вы можете избежать этих проблем, следуя этому подходу:

  1. Чтобы ваш класс имел конструктор без аргументов по умолчанию, который требуется JPA, используйте подключаемый модуль компилятора https://kotlinlang.org/docs/reference/compiler-plugins.html#jpa-support.
  2. Сделать обязательные свойства необнуляемыми (я предполагаю, что только hint является необязательным)
  3. Используйте столько вторичных конструкторов, сколько хотите

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    val id: Int, 

    val username: String,
    val hint: String?, 
    val password: String
) {
    constructor(
        username: String,
        hint: String = null,
        password: String = "change it"
    ) : this(0, username, hint, password)
}

В более реалистичном сценарии неизменными были только id и username. password и hint должны быть разрешены для изменения.

@Entity(tableName = "entry_table")
data class Entry(
    @PrimaryKey(autoGenerate = true) 
    val id: Int, 
    val username: String
) {
    constructor(
        username: String,
    ) : this(0, username)

    var hint: String? = null
    var password: String = "change it"
}

Другие вопросы по теме