我在Scala: can't write setter without getter?中发现你无法在没有getter的情况下创建一个setter:
对作业的解释 一个简单的变量x = e取决于 x的定义。如果x表示a 可变变量,然后是赋值 将x的当前值更改为 评估结果 表达e的类型是 期望符合x的类型。 如果x是无参数函数 在某些模板中定义,并且相同 模板包含一个setter函数 x_ =作为成员,然后赋值x = e被解释为调用 x _ =(e)该setter函数。 类似地,赋值f.x = e到 无参数函数x是 解释为调用f.x _ =(e )。赋值f(args)= e with a 函数应用程序左侧 '='运算符被解释为f.update(args,e) ,即调用 由f。
定义的更新函数
因此,设计决定不允许没有getter的setter。但为什么? 实施起来难度更大,或根本不可能实现吗?
我确实有一个有效的用例,使用它作为一个(有点复杂的)setter,不使用这种语法糖会破坏项目中的所有语法相同的语法。
答案 0 :(得分:1)
您可以尝试从API中排除访问者:
scala> class C { def c_=(i: Int) = println(i) ; private def c: Int = ??? }
defined class C
scala> val c = new C
c: C = C@289fdb08
scala> c.c = 42
<console>:14: error: method c in class C cannot be accessed in C
val $ires0 = c.c
^
<console>:12: error: method c in class C cannot be accessed in C
c.c = 42
^
scala> def f = { c.c = 42 ; 0 }
<console>:12: error: method c in class C cannot be accessed in C
def f = { c.c = 42 ; 0 }
^
在第一个错误中,REPL正在尝试使用访问者报告该值。
配对存取器和增变器的概念称为通用访问原则,因此被访问的成员看起来像属性。
表达式c.c
必须在进一步去除之前进行类型检查。否则,转换(对c.c_=
的调用)必须纯粹是语法。
例如,提供扩展方法c_=
的隐式转换可以发挥作用。