Как инициализировать свойство, не допускающее значения NULL, как указатель this в классе данных kotlin?

Учитывая класс данных Kotlin, как вы инициализируете свойство, не допускающее значения NULL, как указатель на себя? То есть что-то вроде следующего псевдокода.

data class Node(var other: Node = this)

В настоящее время у меня есть решение, которое вводит временные свойства

data class Node(val _other: Node? = null) {
    var other: Node = _other ?: this
}

Зачем использовать val _other? Удалите ключевое слово val

Zoe 10.12.2018 11:02

@Zoe Это дает ошибку "первичный конструктор класса данных должен иметь только параметры свойства val / var"

Benjamin Ingberg 10.12.2018 11:10

Так что не используйте класс данных.

Zoe 10.12.2018 11:11

Спасибо за ваш отзыв, однако для моих целей мне нужны функциональные возможности класса данных, такие как equals и copy, и я бы предпочел не делать свойство обнуляемым и / или реализовывать функциональность вручную.

Benjamin Ingberg 10.12.2018 11:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Это невозможно. Вы не можете получить доступ к this, пока он не будет построен. Но именно так будет работать параметр конструктора по умолчанию.

Cannot access '<this>' before superclass constructor has been called

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

Alexey Romanov 10.12.2018 12:56
Ответ принят как подходящий

Thank you for your feedback, however, for my purposes I need the functionality of a data class like equals and copy and I would prefer not to have make the property nullable and/or implementing the functionality manually.

Вам все равно придется: equals и copy будут заботиться только о _other и игнорировать other (так же, как они игнорировали бы все другие свойства, определенные в теле класса). То, что other - это var, только усугубляет ситуацию: его переназначение не повлияет на функциональность класса данных.

Но можно подойти ближе:

data class Node(private var _other: Node? = null) {
    var other: Node
        get() = _other ?: this
        set(value) {
            _other = if (value != this) value else null
        }
}

Остается только одна проблема: component1() вернет _other. В этом случае у вас есть одно свойство, поэтому это не имеет значения.

Обновлено: немного подумав,

data class Node(private var _other: Node? = null) {
    init {
        this._other = _other ?: this
    }

    var other: Node
        get() = _other!! // safe
        set(value) {
            _other = value
        }
}

кажется, фактически то, что вы хотите. Вы можете увидеть разницу здесь:

val node1 = Node()
val node2 = node1.copy(node1)
println(node1 == node2)

печатает false с первым решением, true со вторым (как и должно быть, если this был параметром по умолчанию).

Благодарим вас за улучшенное решение и разъяснения относительно того, как работает автоматическое копирование / равенство. Из вашего ответа я предполагаю, что мое предпочтительное решение невозможно выразить, но ваш обходной путь, по крайней мере, решает большинство проблем. В фактическом коде я использую более одного свойства, поэтому возвращение _other компонентом1 () прискорбно, но все равно спасибо.

Benjamin Ingberg 10.12.2018 12:36

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