Я, вероятно, думаю об этом неправильно, но у меня возникают проблемы в Scala с использованием линз в классах, расширяющих что-то с помощью конструктора.
class A(c: Config) extends B(c) {
val x: String = doSomeProcessing(c, y) // y comes from B
}
Я пытаюсь создать Lens
для изменения этого класса, но у меня проблемы с этим. Вот что я хотел бы уметь делать:
val l = Lens(
get = (_: A).x,
set = (c: A, xx: String) => c.copy(x = xx) // doesn't work because not a case class
)
Я думаю, что все сводится к тому, чтобы найти хороший способ мутировать этот класс.
Каковы мои варианты достижения чего-то подобного? Я думал об этом двумя способами:
- Переместите логику инициализации в объект-компаньон
A
вdef apply(c: Config)
и измените классA
наcase class
, который создается из объекта-компаньона. К сожалению, я не могу расширитьB(c)
в своемobject
, потому что у меня есть доступ только кc
в его методеapply
. - Сделайте
x
var
. Затем вLens.set
простоA.clone
затем установите значениеx
, затем верните клонированный экземпляр. Это, вероятно, сработает, но выглядит довольно уродливо, не говоря уже о том, что изменение этого числа наvar
может вызвать удивление. - Используйте немного магии отражения, чтобы сделать копию. Не совсем поклонник этого подхода, если я могу избежать его.
Что вы думаете? Я думаю об этом действительно неправильно, или есть простое решение этой проблемы?