我有一个表示 3D 向量的案例类,我正在尝试使用特征来标记每个向量,并带有与每个问题域相关的参考系。 更具体地说,我正在尝试做这样的事情:
trait bFrame
type bVector = Vector with bFrame
/** Inertial position of the point represented in b+ */
def p_b:bVector = Vector(x + r * sP, y - cP*sR*r, z - cP*cR*r) with bFrame
构造函数中的表达式计算结果为双倍,在我尝试这个特质技巧之前一切正常。 我读过您可以将特征应用于类的实例,而不仅仅是类本身,但它似乎在这里不起作用。 我得到的错误是"';'预期,但'有'找到'。 我想使用类型系统来检查参考系,而不必修改原始类。 有没有办法做到这一点?
注释中没有足够的空间来回答
它看起来不像是创建一个新的匿名类。当我添加....
它是=(
例:
$ cat T.scala
trait A
case class T(name: String)
object B extends App {
val a = new T("123") with A
println(a)
}
$ scalac -Xprint:typer T.scala
我跳过了大部分输出 - 您可以自己检查。最有趣的:
...
private[this] val a: T with A = {
final class $anon extends T with A {
def <init>(): <$anon: T with A> = {
$anon.super.<init>("123");
()
}
};
new $anon()
};
<stable> <accessor> def a: T with A = B.this.a;
...
如您所见 - 匿名类初始化。
我想通了。 目前尚不清楚原因,但出于某种原因,Scala(从 2.12.2 开始(不喜欢您使用构建案例类的"应用"方式。 我必须添加"新"才能使其工作。 另外,我最初应该更清楚,Vector 是一个表示数学意义上向量的案例类,而不是 Scala 集合。 我在这里将其更改为Vector3D以使其更清晰。 此外,2.12.2 编译器说打印"b-frame 中的矢量"的行无法访问,但是当我运行它时,该行被执行(即输出是您所期望的(。 也许这是编译器中的一个错误。 我将在更新版本的Scala上尝试一下,看看。
object Test extends App {
case class Vector3D(x:Double, y:Double, z:Double)
trait bFrame
trait nFrame
type bVector3D = Vector3D with bFrame
type nVector3D = Vector3D with nFrame
val p_b:bVector3D = new Vector3D(1.0, 2.0, 3.0) with bFrame //Works
//val p_b:bVector3D = Vector3D(1.0, 2.0, 3.0) with bFrame //Doesn't work
p_b match {
case _:nVector3D => println("Vector in the n-Frame")
case _:bVector3D => println("Vector in the b-Frame") //Compiler says this is unreachable
case _:Vector3D => println("Vector in an undetermined frame")
case _ => println("Something other than a vector")
}
}