Scala类变量名隐藏方法参数名称

时间:2011-07-04 08:39:59

标签: scala variables parameters

我想知道为什么我不能为函数参数和类中使用的名称使用相同的名称。请参考以下示例。

scala> class Person() {var name = "bob" }
defined class Person

scala> val p = new Person
p: Person = Person@486f8860

scala> p.name
res0: java.lang.String = bob

scala> p.name = "alice"

scala> p.name
res1: java.lang.String = alice

scala> def chngName(name:String) = new Person() {this.name= name}
chngName: (name: String)Person

scala> val p = chngName("aa")
p: Person = $anon$1@3fa1732d

scala> p.name
res2: java.lang.String = bob

scala> def chngName(n:String) = new Person() {name= n}
chngName: (n: String)Person

scala> val p = chngName("aa")
p: Person = $anon$1@19d2052b

scala> p.name
res3: java.lang.String = aa

当然,我可以使用不同的名字,但我想知道为什么我不能,或者有一些我想念的东西。感谢

3 个答案:

答案 0 :(得分:3)

new Person()之后传递的块位于Person初始化主体中(如果您愿意,它位于构造函数内)。在此范围中,name被定义为类字段。 (因此namethis.name)相同。

答案 1 :(得分:3)

(为什么要在var中返回新对象时使用chngName?)

如前所述,该类的同名字段会影响方法参数。

您可以在进入课程范围之前重命名它:

def chngName(name:String) = {
  val _name = name
  new Person() { name = _name }
}

对于此用例,还有一些其他选项。但是,这取决于您是否要复制对象,即。返回new Person,或者只需更改var即可。

如果要返回一个全新的对象,可以考虑使用case class添加copy方法,该方法具有相同的语义和相同名称的方法参数。 (所以你可以使用命名参数):

case class Person(name: String)
val p = Person("bob")
p.name // bob
val q= p.copy(name = "aa")
q.name // aa
q == p // false

答案 2 :(得分:-1)

这可以按预期工作(虽然不那么简洁)

 def chngName(name:String) = {val r = new Person; r.name=name; r;}