我有一个表示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
在我尝试这个特征技巧之前,构造函数中的表达式求值为double,并且一切正常。我已经读到你可以将特征应用于类的实例,而不仅仅是类本身,但它似乎在这里工作。我得到的错误是"';'预期,但'与'发现&#34。我想使用类型系统来检查参考帧而无需修改原始类。有没有办法使这项工作?
答案 0 :(得分:1)
评论中没有足够的空间来回答
它看起来不像创建一个新的匿名类。当我添加....
是=)
示例:
$ 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;
...
你可以看到- 匿名类初始化。
答案 1 :(得分:0)
我想我明白了。目前尚不清楚原因,但由于某些原因,Scala(截至2.12.2)并不希望您使用&#34; apply&#34;构建案例类的方法。我必须添加&#34; new&#34;使它工作。另外,我原本应该更清楚的是,Vector是一个案例类,它代表数学意义上的向量,而不是Scala集合。我在这里将其更改为Vector3D以使其更清晰。此外,2.12.2编译器表示在b-Frame&#34;中打印&#34; Vector的行。无法访问,但是当我运行它时,该行被执行(即输出是你期望的)。也许这是编译器中的一个错误。我将尝试使用更新版本的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")
}
}