#kotlin #lazy-loading #lazy-initialization
#котлин #отложенная загрузка #ленивая инициализация
Вопрос:
У меня есть класс данных, который я хочу заполнить, где в одном конструкторе у меня уже есть данные, а в другом я хотел бы извлекать их только тогда, когда это требуется, что случается редко.
Пример кода будет выглядеть следующим образом:
data class Source1(val str1: String)
data class Source2(val str2: String)
data class DTO(val data1: String, val data2: String) {
// ctor which does not need laziness
constructor(source1: Source1) : this(
data1 = source1.str1,
data2 = source1.str1
)
// ctor which needs costly data
constructor(source2: Source2, costlyData: String) : this(
data1 = source2.str2,
data2 = costlyData
)
}
fun demo() {
val source1 = Source1("some str - 1")
DTO(source1)
val source2 = Source2("some str - 2")
val costlyData: String = costlyOperation() // this is the operation I'd like to execute lazily
DTO(source2, costlyData)
}
Комментарии:
1. kotlinlang.org/docs/reference/delegated-properties.html#lazy
Ответ №1:
Я бы сказал, что самым простым способом было бы принять функцию в качестве параметра конструктора, что-то вроде этого:
class DTO(provider:()->String){
constructor(data: String):this({data})
val data by lazy{ provider()}
}
Таким образом, вы можете использовать его обоими способами:
val eager = DTO("some str - 1")
val lazy = DTO(::costlyOperation)
Немного более приятный способ — иметь Source
абстракцию с различными реализациями для предоставления постоянного значения и выполнения операции. Но общая идея была бы той же самой.
Хотя я бы больше не стал называть это DTO, и он теряет свои возможности класса данных в отношении содержимого.