Scala中类参数声明之间的区别

时间:2018-06-19 09:19:09

标签: scala

可以帮助我理解以下两个声明

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!!

我知道默认情况下参数为val。为什么第一个p1能够返回数据而p2无法执行相同的操作

2 个答案:

答案 0 :(得分:2)

从Scala规范正式开始:

  

形式值参数的范围包括所有后续参数部分和模板t。但是,形式值参数可能不构成任何父类或类模板t成员的类型的一部分。定义两个具有相同名称的正式值参数是非法的。

参数部分和模板t基本上描述了整个类范围。

在Scala的JVM实现上,当您在Scala中创建一个类并且没有指定val关键字时,编译器会将该字段的范围设置为private[this]并且不会#39} ; t为外部可见性创建匹配方法。含义(感谢@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>
};

添加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>
};

def添加到字段中,使其在封闭类之外可见,从而在使用网站上可见。

答案 1 :(得分:1)

A class parameter with a val declaration is a public val field of the class.

A class parameter without a val declaration is just like a parameter to any other function. 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. See 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.