加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为什么不适用的隐式转换会引入歧义?

发布时间:2020-12-16 18:47:07 所属栏目:安全 来源:网络整理
导读:此示例的设置( Scala 2.10.3): trait S[A]trait T[A]implicit class X[A : S](a: A) { def foo() { } }implicit class Y[A : T](a: A) { def foo() { } }implicit object I extends S[String] 这编译: new X("").foo() 这不是: new Y("").foo() 因为没有
此示例的设置( Scala 2.10.3):

trait S[A]
trait T[A]
implicit class X[A : S](a: A) { def foo() { } }
implicit class Y[A : T](a: A) { def foo() { } }
implicit object I extends S[String]

这编译:

new X("").foo()

这不是:

new Y("").foo()

因为没有隐含的T [String].

could not find implicit value for evidence parameter of type T[String]
              new Y("").foo()
              ^

因此,我认为scalac可以明确地应用从String到X的隐式转换:

"".foo()

但相反,我们得到:

type mismatch;
 found   : String("")
 required: ?{def foo: ?}
Note that implicit conversions are not applicable because they are ambiguous:
 both method X of type [A](a: A)(implicit evidence$1: S[A])X[A]
 and method Y of type [A](a: A)(implicit evidence$1: T[A])Y[A]
 are possible conversion functions from String("") to ?{def foo: ?}
              "".foo()
              ^

这是故意的吗? scalac是否应该考虑每个转换在枚举候选人时是否真的有效?

解决方法

我的非学术观点是隐含的设计并不意味着每次看起来应该有效.我认为这是一个好主意,否则你很容易陷入隐蔽的地狱.您可以通过添加更多隐式转换层来扩展您的示例.通过查看代码很难分辨实际调用哪个函数.有明确定义的规则,但我记得很简单,如果从代码中发现的事情并不明显,它就不起作用了.

我会说你的代码破了One-at-a-time Rule导致打破了Non-Ambiguity Rule.答:S只是一个语法糖,可以改写为:

implicit class X[A](a: A)(implicit e: S[A]) { def foo() { } }
implicit class Y[A](a: A)(implicit e: T[A]) { def foo() { } }

如果没有“第二”隐式级别(方法参数e)的解析,则类X和Y看起来与编译器相同,因此是不明确的.正如链接文档所说:“为了理智,编译器在已经处于尝试另一个隐式转换的过程中时不会插入进一步的隐式转换.”

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读