Say I wanted to extend Scala's MapLike trait with a concrete implementation, IntIntM开发者_StackOverflow社区ap. In order to do so, I need to implement the following methods,
def get(key: A): Option[B]
def iterator: Iterator[(A, B)]
def + [B1 >: B](kv: (A, B1)): This
def -(key: A): This
What is the This
type? Should my overriding method signature be,
override def +=(kv: (Int, Int)): IntIntMap = {
// logic
}
Or just scala.reflect.This
? What about the class definition? Should it be,
class IntIntMap(...) extends MapLike[Int,Int,This] { ... }
or something else entirely?
You should extend MapLike[Int, Int, IntIntMap]
, and This
becomes IntIntMap
.
You should have a look first at The Architecture of Scala Collections. It shows you how to integrate you own collections.
However, you will have some trouble implementing the +
method in you example, because it should allow to add values matching a supertype of Int and returning an appropriate Map
. Since This
should be a Map[Int,Int]
you will run into trouble.
I would rather recommend to just have a type definition somewhere:
type MapIntInt = Map[Int,Int]
and eventually use implicits to bring specific methods.
Not a reserved word, not the name of some class, but the third type parameter in MapLike.
Type declaration is MapLike[K, +V, +This <: MapLike[K, V, This]
. It could be called any other way. Most of the time, the This should be the actual implementor class, hence the name. in your case
class IntIntMap extends MapLike [Int, Int, IntIntMap].
Without that parameter, +
result type would have be declared MapLike, not IntIntMap. On +
, that would not be a problem, because you have to define it, and doing that you can change the result type. But methods that you don't need to redefine and which are implemented using +
(such as the ++
would still return MapLike.
精彩评论