Имя переменной класса Scala Скрывает имя параметра метода - PullRequest
3 голосов
/ 04 июля 2011

Интересно, почему я не могу использовать одно и то же имя для параметра функции и имя, используемое в классе. Пожалуйста, обратитесь к следующему примеру.

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 ]

3 голосов
/ 04 июля 2011

(Почему вы хотите использовать 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 голосов
/ 04 июля 2011

Блок, который вы передали после new Person(), находится в теле инициализации Person (оно внутри конструктора, если хотите).В этой области name определяется как поле класса.(поэтому name совпадает с this.name).

0 голосов
/ 04 июля 2011

это работает как задумано (хотя и гораздо менее лаконично)

 def chngName(name:String) = {val r = new Person; r.name=name; r;}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...