【问题标题】:constructors in scala (primary/auxiliary/default primary)scala中的构造函数(主要/辅助/默认主要)
【发布时间】:2012-05-12 15:49:12
【问题描述】:

Cay Horstmann 的一书中的一个非常简单的练习«为不耐烦的人准备的 Scala» 一直困扰着我。关于primaryauxiliarydefault primary 构造函数:

前 5.10: 考虑类

class Employee(val name: String, var salary: Double) {
  def this() { this("John Q. Public", 0.0) }
}

重写它以使用显式字段和默认的主构造函数。

我不确定我应该这样做。你们中的一些人可以提出解决方案吗?

但是,尝试解决这个问题可能让我意识到了一些我以前没有注意到的关于主构造函数和 val 字段(如您所见,我不太确定):

如果我说val 字段(如上面Employee 类中的name)只能通过primary 构造函数而不是auxiliary 初始化,我说得对吗?在后一种情况下,编译器会将其视为对 val 字段的重新分配,从而导致错误。

起初我认为 val 字段大致相当于 java 中的 final 字段,希望在任何构造函数中首次分配它们是合法的,但似乎我错了。

我对这可能只是一个疯狂的猜测不太满意,所以如果有人能给我关于这一点的更准确信息,我将不胜感激。

【问题讨论】:

  • 我在同一个练习中遇到了这个确切的问题。也许我对作者所说的“明确”的意思感到困惑。

标签: scala constructor


【解决方案1】:

来自“Scala 编程,第 2 版”第 6.7 段:

在 Scala 中,每个辅助构造函数都必须调用与它的第一个操作相同的类的另一个构造函数。 这条规则的最终结果是,Scala 中的每个构造函数调用最终都会调用该类的主构造函数。因此,主构造函数是类的单一入口点。

所以val初始化的所有数据都必须在主构造函数中。

具有显式字段的类可能类似于:

class Employee(n: String = "John Q. Public", s: Double = 0.0) {
  val name = n
  var salary = s
}

或者没有默认参数值:

class Employee(n: String, s: Double) {
  def this() = this("John Q. Public", 0.0)
  val name = n
  var salary = s
}

【讨论】:

  • 感谢您的回答。我找到了一个与您的解决方案非常接近的解决方案,但认为它不符合练习的目标,因为我认为“默认主构造函数”是“未明确声明的无参数的沉闷构造函数”。
【解决方案2】:

实际上,我想到的是一个没有参数的主构造函数的版本,像这样:

class Employee {
  private var _name = "John Q. Public"
  var salary = 0.0
  def this(n: String, s: Double) { this(); _name = n; salary = s; }
  def name = _name      
}

显然,这不如在主构造函数中定义字段,这是我想要说明的一点。

【讨论】:

  • 非常感谢您花时间阐明练习的目标。也非常感谢您的书,它与 Martin Odersky 的书相得益彰,比任何其他有关该主题的书都更简单、更愉快地学习 Scala。
猜你喜欢
  • 2019-01-10
  • 1970-01-01
  • 1970-01-01
  • 2013-10-22
  • 2018-08-16
  • 2020-11-17
  • 2019-02-20
  • 2014-08-20
  • 1970-01-01
相关资源
最近更新 更多