我有一个特征“Value”和一个扩展类“Equation”,如下所示:
trait Value {
def apply(in: Input): Int
}
class Equation ( eq: Array[Array[Value]] ) extends Value {
override def apply (in: Input) = {
eq.map(addend => addend.map( _(in) ).fold(1)(_ * _) ).fold(0)(_ + _)
}
def this(eq: String) = {
this( eq.replace("-", "+-").split('+').map( _.split('*').map(s => Value(s)) ) )
}
}
(就我的目的而言,除法不是必需的,减法是通过添加某些东西的负数来解决的。我打算在完成完整的字符串解析器后在此处删除辅助构造函数,这是一个不处理括号的快速解决方案)
在尝试将字符串解析为方程式的过程中,我创建了一个 Array[Array[Equation]],因为 Equations 中的 Equations 让我可以处理括号的运算顺序。由于 Equation 是一个值,我希望我可以将此 Array[Array[Equation]] 传递给 Equation 的构造函数,但随后出现以下错误:
overloaded method constructor Equation with alternatives:
[error] (eq: String)spekular.misc.Equation <and>
[error] (eq: Array[Array[spekular.misc.Value]])spekular.misc.Equation
[error] cannot be applied to (Array[Array[spekular.misc.Equation]])
知道我做错了什么吗?我尝试重写 Equation 的构造函数(见下文),但这给我带来了更多错误,而且看起来比必要的复杂:
class Equation [T <: Value] ( eq: Array[Array[T]] ) extends Value { ... }
最佳答案
您观察到的问题归结为 Scala 中的 Array
是 invariant 的。例如:
trait Base
class Derived extends Base
val bases: Array[Base] = Array[Derived](new Derived)
这段代码产生的错误信息更清楚一点:
type mismatch;
found : Array[Derived]
required: Array[Base]
Note: Derived <: Base, but class Array is invariant in type T.
您可以找到有关方差的更多信息,例如here .这个想法基本上是,如果某个类型 Collection[T]
在其类型参数 T
中是不变的,这意味着你不能分配一个Collection[Derived]
类型的值转换为预期类型 Collection[Base]
的变量/参数,反之亦然。
数组是不变的有很好的理由:数组是可变的,如果它不是不变的并且例如协变,那么就有可能违反打字保证:
trait Base
class Derived1 extends Base
class Derived2 extends Base
val derived1s: Array[Derived1] = Array(new Derived1)
val bases: Array[Base] = derived1s
bases(0) = new Derived2 // putting Derived2 in an array of Derived1
val derived1: Derived1 = derived1s(0) // type mismatch
自然,对于“嵌套”类型的构造函数,不变性被传播,因此您不能将 Array[Array[Equation]]
分配给 Array[Array[Value]]
。
解决这个问题的最简单方法是使用一些协变集合(它必然是不可变的):
class Equation(eq: Vector[Vector[Value]]) extends Value {
...
}
Vector[T]
是一个不可变集合,其类型参数是协变的,因此可以将 Vector[Derived]
分配给 Vector[基础]
。因此,您的代码将起作用。
关于scala - 构造函数(特征)不能应用于(类扩展特征),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56589597/