我目前正在考虑重构我的个人线性代数包。 让我困扰的一件事是:实现抽象行为只是一次...特征作为契约,抽象类作为具体帮手
目前我只支持由float
s组成的向量和矩阵。现在我想添加支持int
s,double
s,甚至可能为boolean
s,但我必须考虑这一点。
有一件事:我不想多次写代码。事实上,这是我真正讨厌编程的一件事。我想为某个代码/行为提供单一的责任来源。
对于大多数人来说,好吧,全部操作a矢量有一定的模式。如果我添加两个维持int
s或float
s的二维矢量并不重要,则操作始终是相同的。
现在,天真地我虽然“嗯,这是多难呢?!”对我来说,作为一个Scala-noobie,并不那么容易。
我开始:
trait Vector[Vec <: Vector]
{
def add(v: Vec): Unit
def subtract(v: Vec): Unit
def multiply(v: Vec): Unit
def multiply(s: Numeric): Unit
def dot(v: Vec): Numeric
def length(): Numeric
def distance(v: Vec): Numeric
def normalise(): Unit
def divide(length: Numeric): Unit
def toArray(): Array[Numeric]
}
我想法:添加在绑定会帮我,我继续。
例子:
abstract class Vector2(var x: Numeric, var y: Numeric) extends Vector[Vector2]
{
override def add(v: Vector2): Unit =
{
this.x += v.x
this.y += v.y
}
//...
}
然后我想创建子类型,如:
class IntVector2(var x: Int, var y: Int) extends Vector2
,并用它做。
问题就从这里开始:
abstract class Vector2(var x: Numeric, var y: Numeric) extends Vector[Vector2]
{
override def add(v: Vector2): Unit =
{
this.x += v.x // **here is the problem **
this.y += v.y
}
//...
}
它说
类型不匹配,预计:字符串,实际:数字
我以为我会很聪明的用数字作为上限,因为我假设一个加法将被定义为所有...我有多么错?
我该如何解决这个问题?有任何想法吗?
另外,我忘了之前...
假设我需要使用一个辅助,像math.sqrt(...)
案件。那里做什么?
目前(只实施了float
S,心!)我这样做:
double
S和
int
S也是一样的,我怎么能做出这种通用
def length(): Float =
{
math.sqrt(x * x + y * y).toFloat
}
?等等,而不.toFloat
此外,我充分认识到,与boolean
的I会得到一个问题,因为一些操作只是不是在所有定义......没有理由惊慌,我希望:)
事实上,我想避免暗示,直到我真的,真正了解他们。它们就像我的黑匣子。 – Sorona
有一个可悲的事实:没有它们的scala真棒收藏库不可能如此真棒。你不需要在任何地方忽略所有其他表达手段,因为它没有形状(和其他haskell灵感库)所做的。但有时他们是不可或缺的 – ayvango