繁体   English   中英

Scala中的隐式冲突

[英]Collision of implicits in Scala

以下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起作用,但是当我调用需要带有StringNode参数的函数时仍使用stringToNode吗?

您在这里有含糊的隐式。 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打包到一个对象中,然后仅在需要它的地方将其导入,以使代码可读,并尽可能避免在您也需要冲突的地方进行导入邮编。 但基本上,我会避免使用隐式函数只是为了进行方便的转换。

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

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

Twitter的有效Scala中有关于此问题的部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM