Scala可以在一个表达式中应用多个隐式转换吗?

Bri*_*ent 4 scala

可能重复:
如何在Scala中链接implicits?

Scala可以在一个表达式中应用多个隐式转换吗?

考虑这个简单的例子:

  case class Wrapper(s: String)

  case class WrapperWrapper(w: Wrapper)

  implicit def string2Wrapper(s: String) = Wrapper(s)

  implicit def wrapper2WrapperWrapper(w: Wrapper) = WrapperWrapper(w)

  // implicit conversation -->  w = string2Wrapper("w")
  val w: Wrapper = "w"

  // implicit conversation -->  ww = wrapper2WrapperWrapper(w)
  val ww: WrapperWrapper = w

  // does NOT compile!
  // ideally --> sad = wrapper2WrapperWrapper(string2Wrapper("ww"))
  val sad: WrapperWrapper = "ww"
Run Code Online (Sandbox Code Playgroud)

有没有办法在最后一行中进行"双重"转换?

我可以通过定义另一个隐含的方式帮助事情:

implicit def string2WrapperWrapper(s:String) = wrapper2WrapperWrapper(s)
Run Code Online (Sandbox Code Playgroud)

但似乎不应该这样......

And*_*yle 6

我担心我没有简洁的参考手(答案分散在Scala语言规范的 6.26和第7章),但答案是否定的.

这是由于实用性 - 双隐式转换会使可用转换的数量平方,大大增加了碰撞的可能性,并使得更难以确定给定转换会发生什么.

这不是理想的,你必须申报String,以WrapperWrapper转换自己; 但考虑到在实践中你很少需要这样做,与双重隐含的潜在混淆相比,我认为它是两个邪恶中的较小者.


Don*_*zie 5

您可以相当简洁地强制转换序列:

scala>   val sad: WrapperWrapper = ("ww": Wrapper)           
sad: WrapperWrapper = WrapperWrapper(Wrapper(ww))
Run Code Online (Sandbox Code Playgroud)

正如@Andrzej Doyle所解释的那样,一次两次转换会增加发生意外转换的风险,因此不允许这样做.