[英]Difference Between class parameter declaration in Scala
can some one help me in understand the below two declarations有人可以帮助我理解以下两个声明吗
class Person1(name: String, id: Int) { }
class Person2(val name: String, val id: Int) { }
val p1 = new Person1("personOne", 1)
val p2 = new Person2("personTwo", 2)
println(p1.name) // ERROR
println(p2.name) // OK!!
I know that by default the parameters are val
.我知道默认情况下参数是
val
。 Why the first p1
is able to return data and p2
could not do the same为什么第一个
p1
能够返回数据而p2
不能这样做
Starting formally from the Scala specification:从 Scala 规范正式开始:
The scope of a formal value parameter includes all subsequent parameter sections and the template t.
形式值参数的范围包括所有后续参数部分和模板 t。 However, a formal value parameter may not form part of the types of any of the parent classes or members of the class template t.
但是,形式值参数可能不构成任何父类或类模板 t 成员的类型的一部分。 It is illegal to define two formal value parameters with the same name.
定义两个同名的形式值参数是非法的。
The parameter sections and the template t
basically describes the entire class scope.参数部分和模板
t
基本上描述了整个类范围。
On the JVM implementation of Scala, when you create a class in Scala and don't specify the val
keyword, the compiler sets the scope of the field to private[this]
and doesn't create a matching method for outer visibility.在 Scala 的 JVM 实现上,当您在 Scala 中创建类并且不指定
val
关键字时,编译器会将字段的范围设置为private[this]
并且不会创建外部可见性的匹配方法。 Meaning (thanks @Duelist for the wording) the values are only in scope for the enclosing class (this includes class methods and any lazy fields), nothing more:含义(感谢@Duelist 的措辞)这些值仅在封闭类的范围内(这包括类方法和任何惰性字段),仅此而已:
class Person1 extends scala.AnyRef {
<paramaccessor> private[this] val name: String = _;
<paramaccessor> private[this] val id: Int = _;
def <init>(name: String, id: Int): yuval.tests.Person1 = {
Person1.super.<init>();
()
};
<empty>
};
When you add the val
keyword:添加
val
关键字时:
class Person1 extends scala.AnyRef {
<paramaccessor> private[this] val name: String = _;
<stable> <accessor> <paramaccessor> def name: String = Person1.this.name;
<paramaccessor> private[this] val id: Int = _;
<stable> <accessor> <paramaccessor> def id: Int = Person1.this.id;
def <init>(name: String, id: Int): yuval.tests.Person1 = {
Person1.super.<init>();
()
};
<empty>
};
A def
is added to the fields which makes them visible outside of the enclosing class, thus visible from at the use site.将
def
添加到字段中,使它们在封闭类之外可见,从而在使用站点可见。
A class parameter with a val
declaration is a public val
field of the class.带有
val
声明的类参数是类的public val
字段。
A class parameter without a val
declaration is just like a parameter to any other function.没有
val
声明的类参数就像任何其他函数的参数一样。 It is a constant value whose scope is the whole of the declaration.它是一个常量值,其范围是整个声明。 It can "escape" from the class if it is referenced by a function that is accessible outside the class (method or non-method).
如果它被类外部可访问的函数(方法或非方法)引用,则它可以从类中“逃脱”。
Note : Contrary to other answers to this question, a class parameter without a val
is not a field of the class, though it may be implemented that way.注意:与此问题的其他答案相反,没有
val
的类参数不是类的字段,尽管它可能以这种方式实现。 See https://www.scala-lang.org/old/node/8384.html见https://www.scala-lang.org/old/node/8384.html
Note : A case class
is different in that all parameters to a case class
are public val
fields of that class, with or without an explicit val
before their name.注意:
case class
的不同之处在于case class
所有参数都是case class
的public val
字段,在它们的名称前有或没有显式val
字段。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.