English 中文(简体)
如何在Scala中将Tuple隐式转换为向量
原标题:
  • 时间:2009-04-01 20:13:40
  •  标签:

我想要能够将数字元组(整数和双精度浮点数)隐式转换成向量对象。

假设有一个具有+方法的向量类。

case class Vector(x: Double, y:Double){
  def + (v:Vector)= new Vector(x+v.x,y+v.y)
} 

我的目标是让以下代码能够工作。

val vec = (1,2)+(.5,.3) // vec == Vector(1.5,2.3)

我可以用以下方法让Int正常工作。

implicit def int2vec(t:Tuple2[Int,Int])=new Vector(t._1,t._2)
val vec = (1,2)+(3,4) // vec == Vector(4.0,6.0)

但是当我添加双精度转换时,它出现错误

implicit def int2vec(t:Tuple2[Int,Int])=new Vector(t._1,t._2)
implicit def double2vec(t:Tuple2[Double,Double])=new Vector(t._1,t._2)
val a = (1,2)
val b = (.5,.3)
val c = (1,1)+b // vec = Vector(1.5,1.3)
val d = (1,2)+(.3,.5) // compile error: wrong number of arguments
val e = (1,2)+((.3,.5)) // compile error: type mismatch

尝试遵循Andri的建议来加倍。

implicit def double2vec(t:Tuple2[Double,Double])=new Vector(t._1,t._2)
val a = (.5,.3)
val b = (1,1)+a // type mismatch found:(Double,Double) required:String 

我需要做什么才能让这个工作?

最佳回答

Scala的语法是灵活的,但它并不是无限灵活的。特别是,元组、参数和隐式元素的汇合使得这成为库设计领域中非常危险的区域。正如你注意到的那样,事情很可能会出错,不工作得很好,并给出神秘的错误消息。如果可以的话,我建议你避免这种情况。

特别是,我建议您做出以下定义:

val V = Vector

然后,所有的例子都会按照您的期望运行,没有任何隐式的、魔法的或令人费解的错误信息,而且每个向量只需要一个字符的代价。

val a = V(1,2)+V(.5,.3)
val b = V(1,2)+V(3,4)
val c = V(1,2)
val d = V(.5,.3)
val e = V(1,1)+b
val f = V(1,2)+V(.3,.5)
val g = V(.5,.3)
val h = V(1,1)+a

这并不完全是你想要的语法,但请相信我,它将在长远的路上为你节省痛苦和头痛。

问题回答

这些隐式转换是模糊的,因此Scala不会使用它们之一。这就是为什么最后几行不会被评估的原因。

一种解决方法是完全排除int2vec,虽然这意味着所有整数都将首先隐式转换为双精度。





相关问题
热门标签