我已经创建了一个类,这个类可以由任何可以转换为Numeric的东西参数化
class Complex[T <% Numeric[T]] (val real : T, val imag : T) {
//... complex number methods ...
}然后在代码的其他地方我尝试:
var myComplex = new Complex(0, 1)这会引发编译错误,因为(令人惊讶的是)在Int和NumericInt之间甚至在Int和IntegralInt之间没有隐式转换。
我是不是遗漏了什么?有没有我看不到的隐式转换?
在Numeric.scala中定义了一个名为IntIsIntegral的隐式对象。我试着用它来创建我自己的隐式转换方法:
def implicit intToNumericInt(val i : Int)(implicit n : IntIsIntegral) = n.fromInt(i)我很惊讶这是必需的,而且不管怎样,它似乎会导致对.fromInt方法的无限递归。
我确信我遗漏了一些基本的东西(如您所知,我是Scala的新手),所以如果您能在正确的方向上指出一点,我将不胜感激。
正如您从示例中看到的,我正在尝试实现一个复数实现,它可以接受和使用任何数值类型。我希望对scalala (线性代数)项目做出贡献。接下来,我想介绍一个特征,它描述了矩阵中元素的职责(主要是+和*运算符),并将对复数的支持改进到矩阵操作库中。
发布于 2010-10-27 20:52:26
你用错了。正确的用法如下:
class Complex[T](val real : T, val imag : T)(implicit num: Numeric[T]) {
import num._ // make implicit conversions available
//... complex number methods ...
}这与Ordered和Ordering之间的区别是一样的。可以将Ordered[T]实例与T进行比较,而Ordering[T]提供了一种比较多个T的方法。
发布于 2010-10-27 22:10:42
在Scala2.8中,它也可以写成
class Complex[T: Numeric] (val real : T, val imag : T) {
def +(that: Complex[T]) = {
val r = implicitly[Numeric[T]].plus(this.real, that.real)
val i = implicitly[Numeric[T]].plus(this.imag, that.imag)
new Complex(r, i)
}
}无可否认,这种语法有点密集,但可以像这样使其更具可读性:
class Complex[T: Numeric] (val real : T, val imag : T) {
val num = implicitly[Numeric[T]]
def +(that: Complex[T]) = {
new Complex(num.plus(this.real, that.real), num.plus(this.imag, that.imag))
}
}声明class C[T: M]( ... ) { val x = implicitly[M[T]]似乎等同于前面解决方案的注释中提到的class C[T]( ... )(implicit x: M[T]) { import x._。它不是简单的语法糖,因为它的编译方式是不同的,例如,在第一种情况下,x是一种方法,在第二种情况下,它是一个字段。
https://stackoverflow.com/questions/4033021
复制相似问题