首页 文章

Scala - 将Int隐式转换为数字[Int]

提问于
浏览
5

我已经创建了一个类,可以通过任何可以转换为数字的东西进行参数化

class Complex[T <% Numeric[T]] (val real : T, val imag : T) {
   //... complex number methods ...
}

然后我尝试在代码中的其他地方:

var myComplex = new Complex(0, 1)

这会引发编译错误,因为(令人惊讶的是)Int和Numeric [Int]之间甚至Int和Integral [Int]之间都没有隐式转换 .

我错过了什么吗?在某处我没有看到隐含的转换吗?

在Numeric.scala中定义了一个名为IntIsIntegral的隐式对象 . 我尝试使用它来创建自己的隐式转换方法:

def implicit intToNumericInt(val i : Int)(implicit n : IntIsIntegral) = n.fromInt(i)

我很惊讶这是必需的,无论如何,它似乎导致无限递归到.fromInt方法 .

我确信我遗漏了一些基本的东西(你可以说,我是Scala的新手),所以我会很欣赏正确的方向 .

从示例中可以看出,我正在尝试使用可以接受和使用任何数字类型的复数实现 . 我希望将此贡献给scalala(线性代数)项目 . 接下来,我想介绍一个Trait,它描述矩阵中元素的责任(主要是just和*运算符),并将复数的改进支持到矩阵操作库中 .

2 回答

  • 2

    你错了 . 正确的用法是这样的:

    class Complex[T](val real : T, val imag : T)(implicit num: Numeric[T]) {
       import num._ // make implicit conversions available
       //... complex number methods ...
    }
    

    它与 OrderedOrdering 之间的区别相同 . 可以将 Ordered[T] 实例与 T 进行比较,而 Ordering[T] 提供比较几个 T 的方法 .

  • 9

    在Scala 2.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 是一种方法,在第二种情况下它是一个字段 .

相关问题