首先,为someProperty
设置一个默认值(零)会使事情变得更容易一些。在你的情况下,我想你可以选择Must
或MustNot
,这取决于你的问题的具体情况。
我假设的T
以下定义及其默认:
sealed trait T
object T {
final val Default: T = Must
}
case object Must extends T
case object MustNot extends T
case object Should extends T
你可以有以下实施MySet
,推迟大多数操作其set
属性,有的以它的同伴对象。另外请注意,有些方法如filter
不使用CanBuildFrom
,因此您必须覆盖newBuilder
方法。
class MySet[A](val someProperty: T, set: Set[A])
extends Set[A] with SetLike[A, MySet[A]] {
def +(elem: A): MySet[A] = new MySet[A](someProperty, set + elem)
def -(elem: A): MySet[A] = new MySet[A](someProperty, set - elem)
def contains(elem: A): Boolean = set contains elem
def iterator: Iterator[A] = set.iterator
override def companion = MySet
override def empty: MySet[A] = MySet.empty[A]
// Required for `filter`, `take`, `drop`, etc. to preserve `someProperty`.
override def newBuilder: mutable.Builder[A, MySet[A]] =
MySet.newBuilder[A](someProperty)
}
至于同伴object MySet
,有可能延长SetFactory[MySet]
或其他一些基础类集合同伴对象。这实现了MySet.empty[A]
和MySet.apply[A](as: A*)
的实现,其使用默认值someProperty
创建MySet
。
object MySet extends SetFactory[MySet] {
// For the builder you can defer to the standard `mutable.SetBuilder`
class MySetBuilder[A](someProperty: T) extends
mutable.SetBuilder[A, MySet[A]](new MySet(someProperty, Set.empty))
def newBuilder[A] = newBuilder[A](T.Default)
// Additional method for creating a builder with a known value of `someProperty`
def newBuilder[A](someProperty: T) = new MySetBuilder[A](someProperty)
// You may also want to define `apply` and `empty` methods
// that take a known `someProperty`.
// `CanBuildFrom` from `MySet[_]` to `MySet[A]`.
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, MySet[A]] =
new CanBuildFrom[Coll, A, MySet[A]] {
// This is the method that makes
// e.g. `map`, `flatMap`, `collect` preserve `someProperty`
def apply(from: Coll): mutable.Builder[A, MySet[A]] =
newBuilder[A](from.someProperty)
def apply(): mutable.Builder[A, MySet[A]] = newBuilder[A]
}
}
如果我理解正确,你会发现延长乏味,但你发现不会延长繁琐以及? :) – slouc
@slouc我发现没有延长繁琐,并延长困难/不可能。尽管如此,将会更好。 – Lasf
我同意扩展是困难的,你提供了一些证明你自己的SO链接。如果你想避免手动设置地图和foldLefts,你可以从Set到你的类的隐式转换,它为你的设置增加了一层额外的功能。基本上你会[继承](https://en.wikipedia.org/wiki/Composition_over_inheritance)。这也是您提供的链接中建议的内容。 – slouc