2011-07-04 107 views
3

我想知道爲什麼我不能使用同一個名稱作爲函數參數和類中使用的名稱。請參考下面的例子。Scala類變量名稱隱藏方法參數名稱

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

scala> val p = new Person 
p: Person = [email protected] 

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 = [email protected] 

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 = [email protected] 

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

當然,我可以使用一個不同的名字,但我想爲什麼我不能或有我在這裏錯過的東西。謝謝

+4

在你的榜樣,你可以只定義'類Person(VAR名稱:字符串=「鮑勃」)',然後寫'新Person'獲得鮑勃,或'新人(「aa」)爲自定義名稱。 –

回答

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 
3

您在new Person()之後通過的塊位於Person初始化主體(如果您願意,它在構造函數內部)。在此範圍內name被定義爲類字段。 (所以namethis.name相同)。

+0

我想那麼多。如何引用超出類範圍的函數參數名稱? – thlim

+0

在初始化塊我不認爲你可以。你必須提供一個不同的名字。順便說一句,請參閱Jean-Phillipe對更加習慣解決方案的評論。 – paradigmatic

-1

這個工程按預期(儘管要少得多簡潔)

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

它沒有把重點放在這個問題上。 – 2012-02-20 18:49:48