7

MathUtil というユーティリティ クラスを作成します。

そしてそれはこのように見えます。

abstract class MathUtil(T:Numeric){
   def nextNumber(value:T)
   def result():T
}

このようにサブクラス化しましょう

class SumUtil[T:Numeric] extends MathUtil[T]{
   private var sum:T = 0
   override def nextNumber(value:T){
     sum = sum + value
   }
   override def result():T = sum
}

発言に問題がある

private var sum:T = 0

ここで、合計を 0 にするように初期化する必要があります。0 を表す方法がある数値を推測します。私は scala を初めて使用します。この問題を解決するにはどうすればよいですか?

4

2 に答える 2

12

Numeric型クラスのインスタンスには、必要なことを行うzeroメソッドがあります。

class SumUtil[T: Numeric] extends MathUtil[T] {
   private var sum: T = implicitly[Numeric[T]].zero
   override def nextNumber(value: T) {
     sum = implicitly[Numeric[T]].plus(sum, value)
   }
   override def result(): T = sum
}

plusをインポートNumeric.Implicits._しない限り、メソッドのインスタンスも必要であることに注意してください+。この場合、コンテキスト バインド構文を使用しないことで、コードを少しきれいにすることもできます。

class SumUtil[T](implicit ev: Numeric[T]) extends MathUtil[T] {
   import Numeric.Implicits._
   private var sum: T = ev.zero
   override def nextNumber(value: T) {
     sum = sum + value
   }
   override def result(): T = sum
}

これはまったく同じです: コンテキストにバインドされたバージョンは、この暗黙の引数の単なるシンタックス シュガーですが、その引数を明示的に使用する必要がある場合 (ここで のようにzero)、脱糖バージョンを作成する方がクリーンだと思います。

于 2012-06-22T20:12:02.077 に答える
0

あなたが達成しようとしていることを正確に少し明確にする必要があると思います。Scala docs から、 Numeric 型自体はジェネリックです。ここでの私の気持ちは、コードが現在記述しているものである Numeric[_] のサブクラスではなく、Numeric[T] を処理する MathUtil 抽象化を記述することです。その仮定に基づく正しい実装を次に示します。

//Define a MathUtil that works on any T
abstract class MathUtil[T] {
    def nextNumber(value: T)
    def result(): T
}

//Define a SumUtil that works on any T that has an available Numeric
//Will search implicit scope, but also allows you to provide an
//implementation if desired.
class SumUtil[T](implicit n: Numeric[T]) extends MathUtil[T] {
    //Use the Numeric to generate the zero correctly.
    private var sum: T = n.zero
    //Use the Numeric to correctly add the sum and value
    override def nextNumber(value: T) = sum = n.plus(sum, value)
    override def result(): T = sum
}

//Test that it works.
val a = new SumUtil[Int]
val b = List(1,2,3)

b map a.nextNumber //Quick and dirty test... returns a meaningless list
println(a.result)  //Does indeed print 6

上記で希望どおりの結果が得られない場合は、質問を明確にしてください。

于 2012-06-22T21:09:00.423 に答える