Scala неизменяемые объекты и черты с полями val

Я хотел бы построить свою модель предметной области, используя только неизменяемые объекты. Но я также хочу использовать черты с полями val и перенести некоторые функциональные возможности в черты. Пожалуйста, посмотрите на следующий пример:

trait Versionable {
 val version = 0
 def incrementVersion = copy(version=version+1)
}

К сожалению, такой код не работает - метод копирования неизвестен для свойства Versionable.

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

Итак, в следующем примере:

class Customer(val name: String) extends Versionable {
 def changeName(newName: String) = copy(name = newName)
}

val customer = new Customer("Scot")

customer.changeName("McDonnald") должен вернуть экземпляр объектаCustomer(version = 0, name = "McDonnald")

а также

customer.incrementVersion должен также вернуть экземпляр объектаCustomer(version = 1, name = "Scot")

Насколько я знаю, в настоящее время отсутствие такой функциональности в Scala не позволяет использовать неизменяемые классы и признаки, не загрязняя конструктор классов полями свойств. В моем примере я не хочу вводить параметр с именем version в класс Customer, поскольку функциональность обработки версий я хочу включить в свойство Versionable.

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

Мои вопросы:

1) у вас есть идея, как элегантно справиться с приведенным выше примером. Я довольно новичок в Scala, так что, возможно, уже есть хорошее решение. На мой взгляд, элегантные решения должны иметь следующие особенности:

не следует использовать отражение

не следует использовать сериализацию

должен быть быстрым

должен проверяться во время компиляции

2) что вы думаете о написании плагина компилятора для генерации кода для метода копирования для моего примера выше? Возможно ли это сделать с помощью компилятора? У вас есть примеры или советы, как это сделать?

Ответы на вопрос(5)

Ваш ответ на вопрос