0

次の Scala コードをコンパイルしようとしています。

// Something that Scala is very bad at: don't try and figure out if every type I *could* possibly use supports it,
// just let me use it until I try a type that doesn't.  Or at least have AnyValue provide an abstraction for all
// Numeric Types (Interface)
trait NumericValue[T] {
  def +(rhs : T, lhs : T) : T
}
implicit object ByteNumericValue extends NumericValue[Byte] {
  def +(rhs : Byte, lhs : Byte) : Byte = (rhs + lhs).toByte
}
implicit object ShortNumericValue extends NumericValue[Short] {
  def +(rhs : Short, lhs : Short) : Short = (rhs + lhs).toShort
}
implicit object IntNumericValue extends NumericValue[Int] {
  def +(rhs : Int, lhs : Int) : Int = rhs + lhs
}
implicit object LongNumericValue extends NumericValue[Long] {
  def +(rhs : Long, lhs : Long) : Long = rhs + lhs
}
implicit object BigIntNumericValue extends NumericValue[BigInt] {
  def +(rhs : BigInt, lhs : BigInt) : BigInt = rhs + lhs
}

def doMath[T <: AnyVal](initializer : Long)(implicit Num : NumericValue[T]) : T = {
  Num.+(initializer.asInstanceOf[T], initializer.asInstanceOf[T])
}

lazy val math = doMath[Short](0)

ここでの考え方は、doMath を任意の Integer で動作させる方法が必要であり、したがって加算演算子を含む型が必要であるということです。BigInt のような大きな数や Byte のような非常に小さな数にとらわれないようにしたいのです。

これをコンパイルしようとすると、エラーが発生します。

error: could not find implicit value for parameter Num: NumericValue[Short]
lazy val math = doMath[Short](0)

何か案は?

4

2 に答える 2

0

レックスは正しいです。x:Longは、x.asInstanceOf [Short]が無効であることを意味するため、Tが短いときに初期化子をTにキャストしようとすると、ルーチンは失敗します。はい、それは正当なようです。ありがとうレックス!コメントする代わりにあなたが答えてくれたらいいのにと思います。そうすれば私はあなたに+1を与えることができます。

初期化子のタイプをある程度制御でき、Byteがその論理タイプであることを考えると、doMathの実際の実装ではパラメーターを使用して遅延値タイプを取得するため、これが唯一の問題であることを確認するために少し考える必要があります。出力を制御するオプションの束で。しかし、上記は最も単純な形であり、あなたは頭に釘を打ったと思います。レックスカーありがとう!

于 2012-10-18T21:12:57.437 に答える
0

暗黙のオブジェクトはダメです。

代わりにケースクラスを使用してみてください

例えば:

case class LongNumericValue(l: Long) extends NumericValue[Long] {
  def +(l2 : Long) : Long = l + l2
}

def doMath[T <: AnyVal](implicit Num : NumericValue[T]) : T = {
  Num + Num
}

説明します: 上記の例では、doMath は NumericValue[T] 型 (つまり、NumericValue[Long]) の単一の値を取りますが、受け取った値が Long 型の場合、コンパイラはそれに対する暗黙の値、ケース クラスを探します。

私は自分のコンピューターを持っていないので、これをテストすることはできませんが、過去にそのように変数を初期化しようとしたときにそうでした。

于 2012-10-19T00:02:12.533 に答える