Scala中隐含的碰撞

时间:2013-03-05 19:10:51

标签: scala implicit-conversion implicit

以下Scala代码正常运行:

val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)

但是,如果我导入隐式方法

implicit def stringToNode(str: String): xml.Node = new xml.Text(str)

然后Scala(2.10)编译器显示错误:value zip is not a member of String

似乎stringToNode的存在会以某种方式阻止str1str2WrappedString的隐式转换。为什么?有没有办法修改stringToNode以使zip有效,但当我调用需要stringToNode参数且Node的函数时,String仍在使用?

2 个答案:

答案 0 :(得分:6)

你这里有含糊不清的含义。 StringOps和xml.Node都有zip方法,因此隐式转换是不明确的,无法解析。我不知道为什么它没有给出更好的错误信息。

以下是一些支持它的链接: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOpshttp://www.scala-lang.org/api/current/index.html#scala.xml.Node

编辑:它是StringOps,而不是WrappedString,更改了链接:)看看Predef:http://www.scala-lang.org/api/current/index.html#scala.Predef $ 在Scala中查看预定义的含义。

在这种情况下,我会避免使用含义。您需要2个不同的隐式转换,它们都提供相同名称的方法(zip)。我不认为这是可能的。此外,如果您导入xml.Text,则可以使用Text(str)进行转换,这对任何人都应该足够简洁。如果你必须将这个隐式转换为xml.Node,我会将隐式def打包到一个对象中,然后只在你需要它的地方导入它以使你的代码可读,并且可能避免在你需要的地方发生冲突拉链。但基本上,我会非常避免使用含义来进行方便的转换。

答案 1 :(得分:3)

与@Felix一样,在类似的数据类型之间定义隐式转换通常是个坏主意,就像你使用的那样。这样做会削弱类型系统,导致你遇到的模糊不清,并且可能产生非常不清楚("魔法")代码,这些代码很难分析和调试。

Scala中的隐式转换主要用于定义轻量级,短期包装器,以便丰富包装类型的API。将String转换为WrappedString的隐式转换属于该类别。

Twitter' Effective Scala有一个关于此问题的部分。