Есть несколько проблем с вашим кодом:
Set[Int]()
не является допустимым типом для mySet
, вы должны удалить ()
- member
mySet
должно быть val
, а не def
- , для которого вы вызываете методы apply (), которых не существует
- , если вы хотите подключиться к иерархии коллекций наУровень прохождения, вы не получите методы, такие как
+
и производные +=
.Если вы представляете набор, то это должен быть Set
.
Вот пересмотренная попытка:
import mutable.Builder
import generic.CanBuildFrom
class MyClass private (val prop: String, private val mySet: Set[Int] = Set())
extends immutable.Set[Int] with SetLike[Int, MyClass] {
def -(elem: Int) = MyClass(prop, mySet - elem)
def +(elem: Int) = MyClass(prop, mySet + elem)
def contains(elem: Int) = mySet.contains(elem)
def iterator = mySet.iterator
override def empty: MyClass = MyClass(prop)
override def stringPrefix = "MyClass(" + prop + ")"
}
object MyClass {
def DefaultProp = "DefaultProp"
def apply(prop: String, mySet: Set[Int] = Set()) = new MyClass(prop, mySet)
def newBuilder(prop: String = DefaultProp): Builder[Int, MyClass] =
Set.newBuilder[Int] mapResult (set => MyClass(prop, set))
implicit def canBuildFrom: CanBuildFrom[MyClass, Int, MyClass] =
new CanBuildFrom[MyClass, Int, MyClass] {
def apply(): Builder[Int, MyClass] = newBuilder()
def apply(from: MyClass): Builder[Int, MyClass] = newBuilder(from.prop)
}
}
Тогда вы можете написать:
var obj = MyClass("hello")
obj += 1
println(obj) // prints MyClass(hello)(1)
obj = obj map (_ + 1)
println(obj) // prints MyClass(hello)(2)
Давайте рассмотрим, что:
MyClass
теперь явным образом является неизменным набором с пользовательским представлением, объявленным в аргументах типа для SetLike
.prop
является публичным членом val;фактический набор, mySet
, является частным значением.
Затем нам нужно реализовать четыре операции, на которые опирается Set
, просто перенаправив их mySet
.(Это похоже на то, что это может быть учтено. Для Seq
есть класс SeqForwarder
, который выполняет аналогичную работу, хотя я не смог найти SetForwarder
, хотя).Наконец, мы предоставляем метод empty
, на который также опирается встроенный унаследованный компоновщик.Наконец, переопределение stringPrefix
включает более хорошее представление строки с «MyClass» и значением prop
.
. Обратите внимание, что canBuildFrom
object MyClass
вызывает newBuilder
, передавая prop
изоригинальная коллекция, когда это возможно.Это означает, что большую часть времени вы можете сохранять это значение при отображении и т. Д. Для MyClass
экземпляров.Нам нужно определить значение по умолчанию для prop
, однако, поскольку CanBuildFrom
s должен определить метод apply
, который не сообщает, что такое исходная коллекция.(Вопрос: почему это на самом деле произошло?)
Наконец, наша реализация newBuilder
больше не полагается на ArrayBuffer
s, а непосредственно создает экземпляр Set
, который будет обернут вашим новымMyClass
instance.
Еще несколько ресурсов: