【问题标题】:Scala Constructor Confusion - please clarifyScala构造函数混淆 - 请澄清
【发布时间】:2015-10-20 05:31:35
【问题描述】:

我对 Scala 构造函数感到非常困惑。例如,我有以下类表示一棵树,其中包含运算符,例如 Add 和树上的叶节点,它们都是数字。

abstract class Node(symbol: String) {}

abstract class Operator(symbol: String,
      binaryOp: (Double, Double) => Double ) extends Node(symbol) {
}

class Add(a: Number, b: Number) extends 
      Operator("+", (a: Double, b: Double) => a+b ) {
}

class Number(symbol: String) extends Node(symbol) {
    val value = symbol.toDouble
    def this(num: Double) {
      this(num.toString)
    }
}

我在一个网站上读到,Scala 构造函数中的内容是自动不可变的 (val),但是 Stack Overflow 上的这个人说 "The input parameters for the constructor are not vals unless you say they are." 所以这是一个矛盾。

另外,出于某种原因,我显然可能需要也可能不需要在构造函数中添加“val”和“override”?我的意思是我希望一切都是公开的和不可变的,并且 Add 有一个等于“+”的符号,一个 binaryOp 等于加法函数,还有两个数字 a 和 b。有人可以解释一下如何让构造函数在 Scala 中以一种非冗长的方式按预期工作吗?

我希望能够做这样的事情:

addition = Add(Number(1), Number(2))
addition.binaryOp(addition.a.value, addition.b.value)

【问题讨论】:

  • REPL 调用类参数 vals。 class C(x: Int){ def mod(y:Int):Unit = x=y } 产生 error: reassignment to val

标签: java scala constructor


【解决方案1】:

你快到了:Scala 类的构造函数的每个参数在类构建后都会被丢弃,除非类的方法使用它。在这种情况下,它是一个private[this] val

但是,您可以在构造函数参数前简单地添加 val/var 关键字,它将公开val/var

abstract class Node(val symbol: String) {}

通常,如果该字段已在超类中定义,则不会在子类的构造函数中重复:

abstract class Operator(symbol: String, // no val here, only pass to super class
      val binaryOp: (Double, Double) => Double) extends Node(symbol) {
}

class Add(val a: Number, val b: Number) extends 
  Operator("+", (a: Double, b: Double) => a+b ) {
}

现在您可以从类外部访问字段:

addition = Add(Number(1), Number(2))
addition.binaryOp(addition.a.value, addition.b.value)

【讨论】:

  • 可能还值得一提的是,案例类有些不同(默认情况下,参数是 public valss),因为这可能是另一个混​​乱的来源。
猜你喜欢
  • 1970-01-01
  • 2014-06-04
  • 2014-09-20
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 2017-03-18
  • 2012-03-05
  • 1970-01-01
相关资源
最近更新 更多