我在Scala中使用jMonkeyEngine (JMonkeyEngine),到目前为止,它运行得很好,但现在我想问自己,是否有一种为Vector3f (和类似的)类重载操作符的优雅方法。我的第一个想法是继承Vector3f并重载操作符,但是Vector3f是最终的,所以这不是一个选项。接下来,我想也许我可以有一个带有静态方法的单例/scala对象,这些方法可以在Vector3f上运行,如下所示,但这也是行不通的:
object VectorMath {
def *(factor: Float, vector: Vector3f) = vector.mult(factor)
}
//and then somewhere
import VectorMath._
var v = new Vector3f(1,2,3);
var u = 1.2f * v; //this does not work, because Float does not have * overloaded for Vector3f
var u = VectorMath.*(1.2f, v); //this does work, but defeats the purpose因此,我现在所能想到的就是将Vector3f包装在一个新的Scala类中,并将操作符调用委托给适当的Java方法。然而,这有三个缺点:
toVector3f和fromVector3f方法或类似的东西)进行处理。1.2f * v。我的问题是:有人能想出一种方法来使这个更自然/优雅吗?你如何处理类似的问题?或者,是否有我所知道的Scala语法来做这些事情?在C++中,我将创建一个全局操作符,它以float和Vector3f作为参数,并可能使其成为朋友。Scala是如何做到这一点的,还是说这根本不可能?
发布于 2012-06-12 20:44:30
或者有没有我不知道的Scala语法来做这类事情?
是啊,有种说法是:
class VectorMath(f: Float) { def * (v: Vector3f) = v mult f }
implicit def VectorMath(f: Float) = new VectorMath(f)
val v = new Vector3f(1,2,3)
1.2F * v
// treated as: VectorMath(1.2F).*(v)由于Scala2.10的隐式转换也可以编写为:
implicit class VectorMath(f: Float) { def * (v: Vector3f) = v mult f }自2.10以来,还有一些值类由编译器优化以获得更好的性能:
implicit class VectorMath(val f: Float) extends AnyVal { def * (v: Vector3f) = v mult f }发布于 2012-06-12 21:01:17
除了上面提到的隐式类(从Scala2.10开始)之外,您还可以使用价值类来避免创建中间对象。
本质上,您只需使VectorMath在扩展AnyVal上面。如果您不使用VectorMath对象作为方法的返回值,而只是调用VectorMath操作,则不会在运行时为VectorMath分配任何对象。
发布于 2012-06-12 20:45:05
注意事项:这可能导致非常不可读的代码。
您可以使用隐式转换,并在Vector3f周围创建某种包装类(比如Scala标准库本身有几个Java类,例如请看这里集合)。
// Somewhere, for example in a package object
implicit def wrapVector3f (v: Vector3f) = new Vector3fWrapper ( v );
class Vector3fWrapper (v: Vector3f) {
// Use the Vector3f object internally here
// You can now delegate all methods to the underlying Vector3f object
// For example:
def * (v: Vector3f) = {
// ...
}
// or:
def * (f: Float) = {
// ...
}
}https://stackoverflow.com/questions/11004444
复制相似问题