我认为使用Like
特征可以让您改进返回(表示)类型。这涉及更多的工作。相比:
import collection.generic.CanBuildFrom
object FooMap {
type Coll = FooMap[_, _]
implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), FooMap[A, B]] = ???
}
trait FooMap[A, +B] extends Map[A, B] {
def foo = 33
}
def test(f: FooMap[Any, Any]) {
f.map(identity).foo // nope, we ended up with a regular `Map`
}
相对
object FooMap extends collection.generic.ImmutableMapFactory[FooMap] {
override type Coll = FooMap[_, _]
implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), FooMap[A, B]] = ???
def empty[A, B]: FooMap[A, B] = ???
}
trait FooMap[A, +B] extends Map[A, B]
with collection.immutable.MapLike[A, B, FooMap[A, B]] {
def foo = 33
override def empty: FooMap[A, B] = FooMap.empty[A, B]
}
def test(f: FooMap[Any, Any]) {
f.map(identity).foo // yes
}
MapLike
必须在 trait 之后混入traitMap
才能启动正确的返回类型。
看起来你仍然没有免费获得所有东西,例如你需要覆盖更多的方法:
override def +[B1 >: B](kv: (A, B1)): FooMap[A, B1] // etc.