Как создать построитель для класса данных Kotlin со многими неизменяемыми свойствами

У меня есть класс данных Kotlin, который я строю со многими неизменяемыми свойствами, которые извлекаются из отдельных SQL-запросов. Если я хочу построить класс данных с использованием шаблона построителя, как мне это сделать, не изменяя эти свойства?

Например, вместо построения через

var data = MyData(val1, val2, val3) 

Я хочу использовать

 builder.someVal(val1) // compute val2 builder.someOtherVal(val2) // ... var data = builder.build() 

в то же время используя функцию класса данных Kotlin и неизменные свойства.

    Я не думаю, что у Котлина есть отечественные строители. Вы всегда можете вычислить все значения и создать объект в конце.

    Если вы все еще хотите использовать строитель, вам придется реализовать его самостоятельно. Проверьте этот вопрос

    Я согласен с блоком копирования данных в ответе Гжегожа, но это по сути тот же синтаксис, что и создание классов данных с конструкторами. Если вы хотите использовать этот метод и держать все разборчивым, вы, вероятно, будете все заблаговременно вычислять и передавать все вместе в конце.

    Чтобы иметь нечто большее, как строитель, вы можете рассмотреть следующее:

    Предположим, что ваш класс данных

     data class Data(val text: String, val number: Int, val time: Long) 

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

     class Builder { var text = "hello" var number = 2 var time = System.currentTimeMillis() internal fun build() = Data(text, number, time) } 

    Наряду со способом построения:

     fun createData(action: Builder.() -> Unit): Data { val builder = Builder() builder.action() return builder.build() } 

    Действие – это функция, из которой вы можете напрямую изменять значения, а createData будет автоматически создавать ее в классе данных. Таким образом, вы можете создать класс данных с помощью:

     val data: Data = createData { //execute stuff here text = "new text" //calculate number number = -1 //calculate time time = 222L } 

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

    Вы также можете использовать get и set kotlin, указав свои собственные функции для каждой переменной, чтобы он мог делать больше, чем устанавливать поле.

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

    Замечание о добавлении: если вам createData , createData можно сократить до этого:

     fun createData(action: Builder.() -> Unit): Data = with(Builder()) { action(); build() }. 

    «С новым разработчиком примените наше действие и постройте»,

    Нет необходимости в создании пользовательских сборщиков в Котлине – для достижения подобной конструктору семантики вы можете использовать метод copy – это идеально подходит для ситуаций, когда вы хотите получить копию объекта с небольшим изменением.

     data class MyData(val val1: String? = null, val val2: String? = null, val val3: String? = null) val temp = MyData() .copy(val1 = "1") .copy(val2 = "2") .copy(val3 = "3") 

    Или:

     val empty = MyData() val with1 = empty.copy(val1 = "1") val with2 = with1.copy(val2 = "2") val with3 = with2.copy(val3 = "3") 

    Поскольку вы хотите, чтобы все было неизменным, копирование должно происходить на каждом этапе.

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

    Можно механизировать создание классов строителей с помощью обработчиков аннотаций. Я просто создал ephemient / builder-generator, чтобы продемонстрировать это.

    Обратите внимание, что в настоящее время kapt отлично работает для сгенерированного кода Java, но есть некоторые проблемы с сгенерированным кодом Kotlin (см. KT-14070 ). Для этих целей это не проблема, если аннотации нулевой вероятности копируются из исходных классов Kotlin в сгенерированные Java-сборщики (так что код Kotlin с использованием сгенерированного кода Java видит типы с нулевым / непустым значением, а не только с платформой типов).

    Intereting Posts
    Смарт-бросок в BootsrapButton невозможен, потому что endtrip является изменчивым свойством, которое к этому времени изменилось Единый котлинский + libgdx-код для развертывания на Android, рабочий стол и браузер? Ошибка выполнения сервлета Apache Tomcat, написанного в Котлине Котлин: Пропустите и используйте функцию параметров 2? recyclerview onClick getkey из firebase Есть ли лучший способ написать это в котлин? Как заставить Kotlin прекратить использование аргумента для неправильного класса (Интерфейс) Конструктор вложения и объект-компаньон Безусловная инфляция макета из адаптера просмотра. Котлин Пытается запустить скрипт Kotlin в IntelliJ IDEA В чем разница между find и firstOrNull? onActivityResult не называется (Котлин) Kotlin, получающий доступ к членам сопутствующих объектов в производных типах Android Studio / Kotlin: ошибка Gradle – не удается найти метод compile () для аргументов Как добавить +/- функциональность к боттингу в андроиде kotlin