2011-07-10 14 views
2

追加の属性を持つ新しいコレクションがある場合(例:新しい属性のスカラコレクションを拡張する

var v1 = NewColl("foo",Vector(1,2,3)) 
var v2 = v1 filter(_ > 1) 
var v3 = v1 map(_ + 1) 

、その後v2.name=="foo"v3.name=="foo":?:私は、このような場合に(参照herecanBuildFromを定義し、newBuilderんか

class NewColl(var name: String, var values: Vector[Int]) 
    extends IndexedSeq[Int] with IndexedSeqLike[Int, NewColl] {...} 

私は不変なコレクションと一致するように、ここでval Sにあなたのvar Sを変更した

class NewColl(val name: String, val values: Vector[Int]) 
    extends IndexedSeq[Int] with IndexedSeqLike[Int, NewColl] with SeqForwarder[Int] { 
    override def newBuilder: Builder[Int, NewColl] = NewColl.newBuilder(name) 
    protected override def underlying = values 
} 

object NewColl { 
    def apply(name: String, elems: Vector[Int]) = new NewColl(name, elems) 
    implicit def canBuildFrom: CanBuildFrom[NewColl, Int, NewColl] = { 
    new CanBuildFrom[NewColl, Int, NewColl] { 
     def apply(from: NewColl) = from.newBuilder 
     def apply() = newBuilder(defaultName) 
    } 
    } 
    private def newBuilder(name: String) = Vector.newBuilder[Int].mapResult(vector => new NewColl(name, vector)) 
    private def defaultName: String = error("no default name") 
} 

注:

答えて

3

はこれを試してみてください。 SeqForwarderは、valuesの同じメソッドに転送するメソッドのリストの実装を避けるために混在しています。 newBuilderはコンパニオンオブジェクトに実装されており、Stringパラメータが必要です。

CanBuildFromapply()には、元のコレクションを指定せずにコレクションを呼び出すことができます。その場合は、既定の名前を指定するか(ここのように)例外をスローする必要があります(ライブラリを設計せずに新しいコレクションの使用を制御している場合のみ許可されます)。

that questionも参照してください。

+0

グレートが働いているようです!!!あなたはなぜ 'SeqForwarder'を混ぜる必要があるのか​​詳しく説明できますか? – teucer

+0

厳密には必要ではありません。単に、 'def' = values.size'のように、' values'ベクトルに転送されるメソッドの定義をスキップすることができます。 –

+0

SeqForwarderは2.11.0で非推奨になりました – lisak

関連する問題