为什么你不能在scala中创建一个没有getter的setter?

时间:2016-08-25 00:34:53

标签: scala setter design-decisions

我在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,不使用这种语法糖会破坏项目中的所有语法相同的语法。

1 个答案:

答案 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_=的隐式转换可以发挥作用。