5

数値のタプル (Int と double) を暗黙的にベクトル オブジェクトに変換できるようにしたいと考えています。

+ メソッドを持つ Vector クラスを想定する

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)

しかし、double の変換を追加すると失敗します

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 の提案に従って、ちょうど 2 倍にしようとしています

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 

これを機能させるにはどうすればよいですか?

4

2 に答える 2

11

Scala の構文は柔軟ですが、無限に柔軟というわけではありません。特に、タプル、パラメーター、および暗黙の合流点は、これをライブラリー設計空間で非常に危険な領域にします。お気付きのように、物事が壊れたり、うまくいかなかったり、不可解なエラー メッセージが表示されたりする可能性があります。できれば避けたほうがいいと思います。

特に、次の定義を行うことをお勧めします。

val V = Vector

そして、すべての例は、暗黙的、魔法、または不可解なエラーメッセージなしで、Vector ごとに 1 文字だけを犠牲にして、期待どおりに機能します。

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

これはまさにあなたが望む構文ではありませんが、私を信じてください。長い目で見れば、苦痛や頭痛の種から解放されます。

于 2009-04-01T21:13:11.350 に答える
0

これらの暗黙の変換はあいまいであるため、Scalaはどちらも使用しません。これが、最後の行が評価されない理由です。

これを修正する1つの方法は、int2vec完全に除外されますが、これは、すべての整数が最初に暗黙的にDoubleに変換されることを意味します。

于 2009-04-01T20:33:22.600 に答える