暗示太多了!

时间:2011-07-28 00:18:00

标签: scala vector tuples implicit

我正在编写一个2D Vector类,其声明如下:

case class Vec2(x:Float, y:Float) extends (Float, Float)(x, y) {

    def +(v:Vec2) = Vec2(v.x+x, v.y+y)
    //Subtract, dot product, projection, etc.
    ...
    ...
}

我希望能够写出像Vec2(3, 7) + (2, 9)这样的东西,所以我写了

scala> implicit def ii2v2(i:(Int, Int)) = Vec2(i._1, i._2)
ii2v2: (i: (Int, Int))org.zhang.lib.misc.Vec2

scala> Vec2(2, 6) + (3, 1)
res25: org.zhang.lib.misc.Vec2 = (5.0,7.0)

大。但是如果我尝试Vec2(3, 7) + (2.6f, 9.3f),则隐含将无效,因为(Float, Float)(Int, Int)不匹配。我想出的唯一解决方案是为(Int,Int), (Int, Float), (Float, Int), and (Float, Float)写出四个含义。

当您尝试考虑双打或编写Vec3课程时,问题会变得荒谬。有没有解决的办法?我可能只是Vec2-ify所有东西,但我的一部分真的只想添加一个(Int,Int)到Vec2:)

2 个答案:

答案 0 :(得分:11)

这样做:

implicit def ii2v2[T: Numeric, U: Numeric](i:(T, U)) = {
  import Numeric.Implicits._
  Vec2(i._1.toFloat, i._2.toFloat)
}

这使用上下文边界来告诉编译器在数值类型中存在的范围内查找Numeric [T]。自2.9以来可用的导入Numeric.Implicits._允许编写toFloat

在2.8上你可以写:

implicit def ii2v2[T, U](i:(T, U))(implicit num1: Numeric[T], num2: Numeric[U]) = {
  Vec2(num1.toFloat(i._1), num2.toFloat(i._2))
}

请参阅另一个类似的问题:Writing a generic mean function in Scala

答案 1 :(得分:2)

您可能想看看Numeric。另请参阅this question