I have a base class, and subclasses MString and MInt from it.
abstract class Base[T](val name:java.lang.String = "") {
def encode(value:T) : Array[Byte]
}
class MString extends Base[String](name = "string") {
def encode(value:String) = {
Array[Byte](10,20)
}
}
class MInt extends Base[Int](name = "int") {
def encode(value:Int) = {
Array[Byte](100,11)
}
}
I have a map that connects the class name and an instance of it.
val m = Map[String, Base[_]]("string" -> new MString, "int" -> new MInt)
With this map, I was trying to use a string as a key to retrieve the object and invoke the encode method.
println(m("string").encode("A"))
println(m("int").encode(10))
However, I got type mismatch errors:
error: type mismatch;
found : String("A")
required: _$1 where type _$1
println(m("string").encode("A"))
^
/Users/smcho/code/codetemplate/_pl/scala/_learn/exploration/2016/04/03. type_inference.scala:25: error: type mismatch;
found : Int(10)
required: _$1 where type _$1
println(m("int").encode(10))
The solution is to specialize with asInstanceOf
.
println(m("string").asInstanceOf[MString].encode("A"))
println(m("int").asInstanceOf[MInt].encode(10))
Why is this error? Isn't Scala compiler smart enough to invoke the method from the type of its parameter, for example ("A" -> encode(String) and 10 -> encode(Int))?
This is an issue for my code, as I have another map, and it is used to get the encoding results.
val m2 = Map[String, Any]("int"->10, "string"->"A")
m2 foreach {
case (key, value) => m(key).encode(value)
}
Any idea to solve this issue?
Map[String, Base[_]]
. That will be aBase[_]
(of unknown type). The compiler cannot know if it will be aMInt
or aMString
. – Thilo