Объекты данных — это новый функционал, представленный в Kotlin 1.7.20
и планируемый к выпуску в версии 1.9
. Разберемся, для чего он нужен.
Какую проблему призваны решить объекты данных?
Ниже, в типичном примере иерархии запечатанных классов, используется sealed interface
(мог быть и sealed class
), которым определяются возможные состояния экрана профиля: data class
для состояния успеха, а object
для состояний ошибки и загрузки.
sealed interface ProfileScreenState {
data class Success(val username: String): ProfileScreenState
object Error: ProfileScreenState
object Loading: ProfileScreenState
}
А что если нужно занести в журнал или распечатать текущее состояние экрана для отладки либо отправки в службу аналитики? В строковом представлении класса данных ProfileScreenState.Success
как раз содержатся имя класса и все его свойства.
Но если в Kotlin вывести обычное объявление object
, получим строку с полным именем пакета, именем объекта и адресом, где этот объект хранится в памяти. Поскольку объекты в Kotlin — синглтоны, при каждом выводе этого объекта адресная часть останется неизменной и для нас нерелевантной:
com.dataobjects.example.ProfileScreenState$Loading@6d03e736
Success(username=exampleUser1)
com.dataobjects.example.ProfileScreenState$Error@5fd0d5ae
Одно из решений — на каждом объекте реализации переопределить функцию toString(): String
:
sealed interface ProfileScreenState {
data class Success(val username: String) : ProfileScreenState
object Error : ProfileScreenState {
override fun toString(): String = "Error"
}
object Loading : ProfileScreenState {
override fun toString(): String = "Loading"
}
}
Не слишком ли много шаблонного кода для такой тривиальной задачи?
Объекты данных
В Kotlin эту проблему планируют решить с помощью объектов данных. data object
— это обычный object
, но с реализацией по умолчанию функции toString()
, которая выводит его имя без ручного ее переопределения и с соответствием поведения определению data class
. Соответствие поведения классам данных особенно актуально для иерархий запечатанных классов.
Сейчас объекты данных — это экспериментальный функционал. Чтобы его опробовать, указываем компилятору версию Kotlin 1.9
:
kotlinOptions.languageVersion = "1.9"
Синхронизировав проект, получаем в имеющихся объектах — части запечатанной иерархии — предложение преобразовать их в data object
:
После применения предложения объекты преобразуются в data object
:
sealed interface ProfileScreenState {
data class Success(val username: String) : ProfileScreenState
data object Error : ProfileScreenState
data object Loading : ProfileScreenState
}
Выводим их и видим, что строковое представление теперь похоже на data class
и выводится только имя объекта:
Loading
Success(username=exampleUser1)
Error
Заключение
Объекты данных — это новый функционал Kotlin, который улучшает строковое представление object
. Он особенно актуален, когда имеются иерархии запечатанных классов с другими классами данных и их нужно занести в журнал или распечатать для отладки или аналитики.
Обратите внимание: на момент написания этой статьи объекты данных — экспериментальный функционал Kotlin. В будущем их определение может измениться.
Подробнее об объектах данных Kotlin см. в:
Читайте также:
- Класс данных в Kotlin
- Какие языки программирования нужно знать, чтобы разрабатывать приложения под Android?
- Ключевое слово vararg и оператор spread в Kotlin
Читайте нас в Telegram, VK и Дзен
Перевод статьи Domen Lanišnik: Data Objects in Kotlin