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)
但似乎不应该这样......
答案 0 :(得分:6)
我担心我没有简明扼要的参考(答案分散在The Scala Language Specification的第6.26和第7章),但答案是否。
这是由于实用性 - 双隐式转换会使可用转换的数量平方,大大增加了碰撞的可能性,并使得更难以确定给定转换会发生什么。
您必须自己声明String
到WrapperWrapper
转换并不理想;但考虑到你在实践中很少需要这样做,与双重隐含的潜在混淆相比,我认为它是两个邪恶中的较小者。
答案 1 :(得分:5)
您可以相当简洁地强制转换序列:
scala> val sad: WrapperWrapper = ("ww": Wrapper)
sad: WrapperWrapper = WrapperWrapper(Wrapper(ww))
正如@Andrzej Doyle所解释的那样,一次两次转换会增加发生意外转换的风险,因此不允许这样做。