我对 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)
最佳答案
您几乎就在那里:Scala 类的构造函数的每个参数在构造类之后都会被丢弃,除非该类的方法使用它。在本例中,它是一个 private[this] val
。
但是,您可以简单地在构造函数参数前添加 val
/var
关键字,它将成为公共(public) val
/变量
:
abstract class Node(val symbol: String) {}
通常,如果该字段已在父类(super class)中定义,则不会在子类的构造函数中重复此操作:
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)
关于java - Scala 构造函数混淆 - 请澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33228711/