Can someone tell me why, as shown below, an implicit conversion works when simply creating a KeyVal object but does not work when creating a key in a Map that is a KeyVal.
Thank you.
object o {
case class KeyVal(i: Int)
object KeyVal {
implicit def strToKeyVal(s:String) = KeyVal(s.toInt)
}
}
import o._
val x : KeyVal = "1" // Works fine to create a KeyVal
val x : Map[KeyVal, String] = Map("1" -> "One") // Type Mismatch: found (String, String), wants (KeyVal, String)
Scala compiler is not an allmighty thing, and it cant resolve all types of type errors. How should it convert (String, String)
tuple to (KeyVal, String)
tuple and why not to (String, KeyVal)
or (KeyVal, KeyVal)
. Your implicit conversion converts String
to KeyVal
, but not a (String, String)
to KeyVal
. If you add this implicit conversion to the companion object:
implicit def strToKeyVal(s: (String, String)): (KeyVal, String) = (KeyVal(s._1.toInt), s._2)
everything would work fine
It's just a matter of timing. By the time the type of the Map
is considered, you no longer have a String
, but a (String, String)
tuple. This happens because ->
is an operator that is applied first, and then its result is returned for Map
.
If you avoid using that operator, it works:
val x : Map[KeyVal, String] = Map(("1", "One"))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.