【问题标题】:Using implicits for scala map keys对 scala 映射键使用隐式
【发布时间】:2013-07-01 14:21:23
【问题描述】:

有人能告诉我为什么,如下所示,隐式转换在简单地创建 KeyVal 对象时有效,但在作为 KeyVal 的 Map 中创建键时不起作用。

谢谢。

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 implicit scala-2.10


    【解决方案1】:

    Scala 编译器不是万能的东西,它不能解决所有类型的类型错误。它应该如何将(String, String) 元组转换为(KeyVal, String) 元组,为什么不转换为(String, KeyVal)(KeyVal, KeyVal)。您的隐式转换会将String 转换为KeyVal,但不会将(String, String) 转换为KeyVal。如果将此隐式转换添加到伴随对象:

    implicit def strToKeyVal(s: (String, String)): (KeyVal, String) = (KeyVal(s._1.toInt), s._2)
    

    一切都会好起来的

    【讨论】:

    • 谢谢。我猜希望它知道只有 Tuple 的第一个成员需要转换是太多了。但是我不认为这是不合理的,因为它应该知道元组的第一个成员是 KeyVal,因为值是 Map[KeyVal,String]
    【解决方案2】:

    这只是时间问题。在考虑Map 的类型时,您不再拥有String,而是(String, String) 元组。发生这种情况是因为-> 是先应用的运算符,然后将其结果返回给Map

    如果您避免使用该运算符,它会起作用:

    val x : Map[KeyVal, String] = Map(("1", "One"))
    

    【讨论】:

    • 这是有道理的。我想出的另一种方法是使用具有方法的隐式类 KeyVal(s: String): def hold(contents: String) = (this -> contents) 然后映射可以定义为 Map[KeyVal, String] = Map("1" 持有 "One")。这对我有用,因为 KeyVal 实际上是盘子上的井,所以它说井里有一些内容。感谢大家的好答案。
    猜你喜欢
    • 2016-02-25
    • 2016-01-29
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2012-02-26
    • 1970-01-01
    相关资源
    最近更新 更多