从Scala Cookbook中可以看出,如果构造函数变量未使用'var'or'val'定义,则默认情况下Scala不会生成访问器和修饰符方法,但在下面的示例中。
1. class Person2(name : String) {
2. def name = name;
3. def name_=(aName : String) {name = aName}
4. }
我在第2行得到一个编译时间,因为“重载的方法名称需要结果类型”。这是什么意思?我是否重载了名称访问器方法,但是从Cookbook中没有生成访问器和mutator方法。任何人都可以回答这个问题。
答案 0 :(得分:1)
首先,请注意,class Foo(bar: String)
未定义名为bar
的成员变量,只定义构造函数参数。
你仍然可以在类中的任何地方使用它,因为整个类定义在构造函数体内,因此,它本质上是一个闭包,但你将无法为它赋值。所以,如果我们在上一个答案中修正错误
class Person2(aName : String) {
def name = aName
def name_=(aName : String) = { aName = name }
}
这将失败并显示“重新分配给val”消息。
这是因为aName
这里只是一个函数(构造函数)参数,并且所有参数都是不可变的,你不能分配它们。
此外,如果您尝试new Person2("foo").aName
,它也会失败,因为aName
不是Person2
的成员。
现在,问你的问题。与java不同,scala中的方法与变量位于同一名称空间中,因此您不能同时拥有变量和具有相同名称的方法。这就是你得到的编译错误的情况。
当你编写class Person2(val name: String)
时,得到的是在生成的JVM类中定义的私有最终变量name
,它不能在scala中直接访问,方法name()
,回报就是价值。
当您编写class Person2(var name: String)
时,您再次获得一个私有(非最终)JVNM类成员,以及两个scala方法来访问其值。
因此,您提到的cookbook中的“访问器方法”是指访问底层JVM类的成员的值,而不是正在定义的实际scala类。
最后,当您执行class Person2(name: String)
时,您根本没有创建该类的任何成员,因此无法访问。
答案 1 :(得分:0)
Scala编译器在这里与函数和类参数的名称相混淆。这个例子有效:
scala> class Person2(aName : String) {
| def name = aName
| def name_=(name : String) {aName = name}
| }
defined class Person2