簡體   English   中英

Scala中類參數聲明之間的區別

[英]Difference Between class parameter declaration in 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不能這樣做

從 Scala 規范正式開始:

形式值參數的范圍包括所有后續參數部分和模板 t。 但是,形式值參數可能不構成任何父類或類模板 t 成員的類型的一部分。 定義兩個同名的形式值參數是非法的。

參數部分和模板t基本上描述了整個類范圍。

在 Scala 的 JVM 實現上,當您在 Scala 中創建類並且不指定val關鍵字時,編譯器會將字段的范圍設置為private[this]並且不會創建外部可見性的匹配方法。 含義(感謝@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添加到字段中,使它們在封閉類之外可見,從而在使用站點可見。

帶有val聲明的類參數是類的public val字段。

沒有val聲明的類參數就像任何其他函數的參數一樣。 它是一個常量值,其范圍是整個聲明。 如果它被類外部可訪問的函數(方法或非方法)引用,則它可以從類中“逃脫”。

注意:與此問題的其他答案相反,沒有val的類參數不是的字段,盡管它可能以這種方式實現。 https://www.scala-lang.org/old/node/8384.html

注意case class的不同之處在於case class所有參數都是case classpublic val字段,在它們的名稱前有或沒有顯式val字段。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM