2

ScalaでMap[String、Int]が与えられた場合、addメソッドとgetメソッドにロジックを追加できるようにするトレイトを作成したいと思います。これを行うための正しい構文は何でしょうか?(注:それぞれの場合にスーパーメソッドも呼び出したいです)

私は次のようなことを試しました:

var mymap: Map[String, Int] with mytrait[String, Int] = Map[String, Int]()

trait mytrait[A, B] {

    abstract override def +[ B1 >: B] (kv: (A, B1)) : Map[A, B1] = { /* ... */ }

}

しかし、通訳が文句を言うので、特に型パラメーターの使用に関して、構文的に何かが明らかに欠けています。

助けてくれてありがとう

具体的には、コードに既に配置されているマップであるため、プログラムの大きなチャンクを書き直すのではなく、+メソッドにロジックを追加してMapのメソッドを取得し、追加のロジックを実行したいと考えています。プログラムの他の場所でアイテムがマップに追加されるたび。したがって、マップに機能を追加するために特性を選択した理由

これが現在の私のコードです:

    trait RegManager[A, B] extends scala.collection.Map[A, B] {
    case class KeyAlreadyExistsException(e: String) extends Exception(e)

    abstract override def + [B1 >: B] (kv: (A, B1)): scala.collection.Map[A, B1] = {

        super.+[B1](kv)
    }

    abstract override def get(key: A): Option[B] = super.get(key)
    abstract override def iterator: Iterator[(A, B)] = super.iterator
    abstract override def -(key: A): scala.collection.Map[A, B] = super.-(key)
}



var regs = new scala.collection.Map[String, Int] with RegManager[String, Int]

更新: 最終的に、私は仕事を成し遂げたラッパースタイルの実装(デコレーターDP)を選びました。私はScalaのキャリアを始めてまだ6か月なので、特性の機能をまだ正しく理解していない可能性がありますか?!でも素晴らしい言語です!

4

2 に答える 2

1

またはMyTrait[A,B] extends Map[A,B]_MyTrait[A,B] {this: Map[A,B] => ...


申し訳ありませんが、実際には、この方法で機能させることはまずありません。

私の答えの最初の部分は、 MyTrait の宣言が Map を参照していないという事実に関連していたので、 Map の + をオーバーライドする可能性はありません。次のようなものが必要です

trait MyTrait[A,B] extends Map[A,B] {
  abstract override def +[B1 >: B](kv: (A, B1)) : Map[A, B1] = {
    println("adding to map") // this is the new part
    super.+(kv) 
   }
}

ただし、多くの理由により、それほど遠くまで行くことはできません。

宣言で

var mymap: Map[String, Int] with mytrait[String, Int] = Map[String, Int]()

値のMap[String, Int]()タイプは Map であり、特性とは無関係です。mymapタイプの変数を宣言してMap with mytraitも、そうはなりません。コンパイルを妨げるだけです。

MyTrait は、変数の型宣言だけでなく、マップの作成にも表示される必要があります。それは次のようになりますnew Map[A,B] with MyTrait[A,B] ( に注意してくださいnew)。

ただし、Map具象クラスではなく特性であるため、具体的な実装を導入する必要があります。それができた場合は、 + によって返される新しいマップにも MyTrait 型が混在していることに注意する必要があります (もちろん、具体的な実装ではそうではありません)。それ以外の場合は、要素を 1 つ追加すると、MyTrait のない Map に戻ります。

于 2012-08-07T09:50:50.730 に答える
0

既存のオブジェクトに特性を追加することはできません。特性を動的に追加することはできません。オブジェクトの作成時にのみ追加できます。次のいずれかを実行できます。

  1. 質問のコメントで提案されているように、pimp your library patternを使用してください。+ただし、この場合、同じメソッドを使用することはできません。独自のメソッド名を使用する必要があります。
  2. +Map を手動でラップして、引き続きメソッド名として使用できるようにします。
  3. オブジェクトのコピーを作成し、特性を追加します。特に元のマップが大きい場合は、パフォーマンスの問題が発生する可能性があります。
于 2012-08-07T10:43:50.317 に答える