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

时间:2011-11-09 16:41:07

标签: scala

  

可能重复:
  How can I chain implicits in Scala?

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"

有没有办法让最后一行的“双重”转换有效?

我可以通过定义另一个隐含的内容来帮助解决问题:

implicit def string2WrapperWrapper(s:String) = wrapper2WrapperWrapper(s)

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

2 个答案:

答案 0 :(得分:6)

我担心我没有简明扼要的参考(答案分散在The Scala Language Specification的第6.26和第7章),但答案是

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

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

答案 1 :(得分:5)

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

scala>   val sad: WrapperWrapper = ("ww": Wrapper)           
sad: WrapperWrapper = WrapperWrapper(Wrapper(ww))

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