Scala属性赋值实现疑问:自定义类为何无法编译?
问题原因与解决办法
你的代码编译失败主要有两个关键问题:
value_=方法返回类型不符合语法糖要求
Scala里a.value = 3这种赋值写法是语法糖,对应的value_=方法必须返回Unit类型——因为赋值语句本身是无返回值的操作。你写的value_=返回的是copy生成的新A实例(类型为A),这直接违反了语法糖的规则,导致编译报错。没搞清楚不可变类与变量的区别
你用val声明了a,这是个不可变变量;而且case class的字段默认是不可变的。就算你修正了返回类型,copy只会创建新的A实例,原a的引用根本不会变,完全达不到你想要的“赋值改变状态”的效果。
修正方案
方案一:实现真正的可变类(类似Scala Swing组件)
如果要像TextField那样直接修改实例内部状态,得让类内部用可变字段:
class A(var i: Int) { // 必须配套实现getter方法,不然a.value这种读取写法也用不了 def value: Int = i // 修正返回类型为Unit,直接修改内部可变字段 def value_=(j: Int): Unit = i = j } val a = new A(3) a.value = 5 println(a.value) // 输出5
方案二:用var配合不可变case class模拟“赋值”
如果坚持用不可变的case class,得把实例变量声明为var,通过重新赋值新实例来模拟效果:
case class A(i: Int) var a = A(3) // 直接用copy生成新实例并重新赋值,等价于模拟赋值语法的效果 a = a.copy(i = 5) println(a.i) // 输出5
或者把不可变的case class封装到一个可变容器里,对外提供赋值语法:
case class A(i: Int) class MutableA(var inner: A) { def value: Int = inner.i def value_=(j: Int): Unit = inner = inner.copy(i = j) } val ma = new MutableA(A(3)) ma.value = 5 println(ma.value) // 输出5
内容的提问来源于stack exchange,提问作者user79074
相关产品推荐
相关产品推荐

