Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap in scala.collection.mutable is invariant but immutable.HashMap is covariant, why?

Tags:

scala

I want to extends a class with a val of mutable.HashMap[] like this:

class Father
class Son extends Father    

class C1{
  val m = new mutable.HashMap[Int, Father]() 
}

class C2 extends C1{
  override val m = new mutable.HashMap[Int, Son]()
}

And get an error:

Error:(19, 16) overriding value m in class C1 of type scala.collection.mutable.HashMap[Int,ScalaByExample.Father]; value m has incompatible type override val m = new mutable.HashMapInt, Son

I found that immutable.HashMap is covariant but mutable.HashMap is invariant. It works if replace mutable.HashMap with immutable.HashMap.

So my two questions are:

  1. How can I make it works using mutable.HashMap?

  2. Why did scala's author design HashMap like this?

like image 395
Jiang Yukun Avatar asked Oct 03 '16 15:10

Jiang Yukun


People also ask

What are mutable and immutable collections in Scala?

Scala collections systematically distinguish between mutable and immutable collections. A mutable collection can be updated or extended in place. This means you can change, add, or remove elements of a collection as a side effect. Immutable collections, by contrast, never change.

What is immutable map in Scala?

There are two kinds of Maps, the immutable and the mutable. The difference between mutable and immutable objects is that when an object is immutable, the object itself can't be changed. By default, Scala uses the immutable Map. If you want to use the mutable Map, you'll have to import scala. collection.

Is list mutable or immutable in Scala?

Lists are immutable whereas arrays are mutable in Scala.


1 Answers

Mutable maps are invariant because writing to them wouldn't be safe otherwise. Consider for example the following function:

def f(o: C1) {
    o.m(42) = new Father
}

This method is perfectly well-typed. But if you passed in an instance of C2 as the value for o, it'd break because a Map[Int, Son] is not allowed to contain Father objects. Therefore your definition of C2 is ill-typed.

like image 197
sepp2k Avatar answered Oct 01 '22 08:10

sepp2k