2011-07-28 25 views
2

我寫它的聲明看起來像一個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)不匹配。我想出的唯一解決方案是寫出4個implicits,爲(Int,Int), (Int, Float), (Float, Int), and (Float, Float)

當您嘗試考慮雙打時,或者當您編寫Vec3類時,問題變得荒謬。有沒有解決的辦法?我可以只是Vec2-ify一切,但我的一部分只是真的想添加一個(Int,Int)到一個Vec2 :)

回答

11

這樣做:

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

此背景下使用邊界來告訴編譯器尋找一個數字[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

+0

酷的東西!我將不得不更多地關注數字。謝謝! –