2014-01-22 83 views
2

我很难理解主构造函数及其参数的概念。我已经明白到现在为止是:如果我们定义一个类如下scala中主要构造函数参数的可访问性

class Example(a: Int, b: Int) 

Scala编译器生成与上述两个参数的类实例的主要构造。但是,它没有定义字段 a b类别示例的定义。但是,如果我们定义

class Example(val a: Int, val b: Int) 

Scala编译器生成的主构造如上,并增加了在类定义两个字段。

现在的问题,当我试图像

class PrimaryConstructor(a: Int, b: Int){ 
    override def toString() = "PrimaryConstructor(" + this.a + ", " + this.b + ")" 
} 

一个例子上面的代码编译好,即使没有名为领域既一个 b来。我无法理解,如果没有任何字段,那么我如何使用这个来访问它们:当前的对象引用。

object Main{ 
    def main(args: Array[String]){ 
      val primaryConstructor = new PrimaryConstructor(1, 2) 
      println(primaryConstructor.a) 
    } 
} 

虽然如果我尝试从上面的类定义的外侧访问它们,编译后会出现以下错误消息。

error: value a is not a member of PrimaryConstructor 
    println(primaryConstructor.a) 

我可以理解这一点。但是,如何使用这个访问这些字段?请帮我理解这一点。

+1

如果您有一些JavaScript经验,请尝试放弃Java类的概念,而将类视为关闭(函数)作为主构造函数中的参数。 “作为封闭的一切”这个概念是scala的核心概念,一旦你喜欢它,它是非常强大的。主构造函数确保有一个类的关联状态的单一规范表示。 –

回答

3

它基本上产生私有缬氨酸,所以

class A(a:Int) { 
    def func = a 
} 

class A(private[this] val a:Int) { 
    def func = a 
} 

是等价的。如果您省略该功能,这可能并非完全正确。

当在构造函数体外引用构造函数参数时(例如上面的示例func),Scala会生成一个private[this] val,否则将生成一个private[this] val

您可以检查斯卡拉规格的详细信息,或看this stackoverflow question

+0

非常感谢。 我试图用'javap -p PrimaryConstructor'反汇编来查看私有字段,并将它们全部显示出来。 –

2

马丁的答案是伟大的:

它基本上生成一个私人VAL,所以

class A(a:Int) { 
    def func = a 
} 

class A(private[this] val a:Int) { 
    def func = a 
} 

是等效的,您可以访问a从你的班级里面。

但是,请注意class A(a: Int)意味着字段a实例私有。这意味着你可以不写这样的事情:

class A(a: Int){ 
    def sum(other: A): Int = { 
    this.a + other.a 
    } 
} 

other.a是不允许的,即使这两种情况下是相同类型的。您只能使用this.a

相关问题