Tuple2._2用作map.apply中的键

Syn*_*sso 3 scala implicit-conversion

在Scala v2.9.2(和2.8.0)中,此脚本:

case class MyString(s: String)
implicit def stringToMyString(s: String) = MyString(s)
implicit val defaults: Map[String, MyString] = Map("abc" -> MyString("123"))

case class HasDefaults(name: String = "none", 
    baseMap: Map[String, MyString] = Map.empty) {
  def add(kvp: (String, MyString)*)(implicit defaults: Map[String, MyString]) =
    this.copy(baseMap = this.baseMap ++ defaults ++ kvp)
}

val hasDefaults = HasDefaults() add (
  "def" -> "124",
  "xyz" -> MyString("999")
)

println(hasDefaults)
Run Code Online (Sandbox Code Playgroud)

失败:

java.util.NoSuchElementException: key not found: 124
    at scala.collection.MapLike$class.default(MapLike.scala:224)
    at scala.collection.immutable.Map$Map1.default(Map.scala:106)
    at scala.collection.MapLike$class.apply(MapLike.scala:135)
    at scala.collection.immutable.Map$Map1.apply(Map.scala:106)
    at Main$$anon$1.<init>(HasDefaults.scala:12)
Run Code Online (Sandbox Code Playgroud)

它试图将String值"124"用作地图查找中的键,即使它被定义为值(由于位于->运算符的右侧).

请注意,如果MyString未尝试隐式转换,则此错误消失.例如:

val hasDefaults = HasDefaults().add(
  "def" -> MyString("124"),
  "xyz" -> MyString("999")
)
Run Code Online (Sandbox Code Playgroud)

注意#2,如果显式提供隐式参数,错误也会消失.例如:

val hasDefaults = HasDefaults().add(
  "def" -> "124",
  "xyz" -> MyString("999")
)(Map("abc" -> MyString("123")))
Run Code Online (Sandbox Code Playgroud)

mis*_*tor 6

在Scala中,Map是一个函数.(Map[A, B] <: PartialFunction[A, B] <: A => B.)因此defaults就像从隐式转换StringMyString.由于defaults不包含"124",您将收到"未找到密钥"错误.