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

什么是“分歧隐含扩展”的scalac消息是什么意思?

发布时间:2020-12-16 09:01:36 所属栏目:安全 来源:网络整理
导读:我创建了一个小型示例程序,试图找出为什么一个较大的程序没有编译. val o1: Ordered[Int] = 1val o2: Ordered[Int] = 2println(o1 o2) 当我喂这个scala我得到: Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered
我创建了一个小型示例程序,试图找出为什么一个较大的程序没有编译.

val o1: Ordered[Int] = 1
val o2: Ordered[Int] = 2
println(o1 < o2)

当我喂这个scala我得到:

Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method ordered in trait LowPriorityOrderingImplicits
println(o1 < o2)
        ^
one error found

使用“-explaintypes”没有任何进一步的.但是,“-Xlog-implicits”给出了以下内容:

math.this.Ordering.comparatorToOrdering is not a valid implicit value for scala.math.Ordering[Ordered[Int]] because:
could not find implicit value for parameter cmp: java.util.Comparator[Ordered[Int]]
scala.this.Predef.conforms is not a valid implicit value for Ordered[Int] => java.lang.Comparable[Ordered[Int]] because:
type mismatch;
 found   : <:<[Ordered[Int],Ordered[Int]]
 required: Ordered[Int] => java.lang.Comparable[Ordered[Int]]
/Users/steshaw/Projects/playground/scala/programming-in-scala/Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method ordered in trait LowPriorityOrderingImplicits
println(o1 < o2)
        ^
math.this.Ordering.comparatorToOrdering is not a valid implicit value for scala.math.Ordering[Ordered[Int]] because:
could not find implicit value for parameter cmp: java.util.Comparator[Ordered[Int]]
scala.this.Predef.conforms is not a valid implicit value for Ordered[Int] => java.lang.Comparable[Ordered[Int]] because:
type mismatch;
 found   : <:<[Ordered[Int],Ordered[Int]]
 required: Ordered[Int] => java.lang.Comparable[Ordered[Int]]
one error found

但这不是帮助我.想知道这个消息的意思和解决方法?

[更新]今天与Scala 2.11.0相同的代码除了第一个关于“发散隐式扩展”之外还会生成第二个错误消息.这第二个消息是非常有帮助的.

$scala Ordered.scala
Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
println(o1 < o2)
        ^
/Users/steshaw/Projects/playground/scala/scalac-errors/Ordered.scala:3: error: type mismatch;
 found   : Ordered[Int]
 required: Int
println(o1 < o2)
             ^
two errors found

解决方法

很快:你的错误消息应该是简单的
????错误:类型不匹配
????发现:订购[Int]
????必需:国际

原因只是在有序[A]中,与A进行比较,而不是与其他订单进行比较

def <(that: A): Boolean

那应该是o1 2,不是o1 < O2. (当然1< 2也是,但我希望你的代码只是简单的其他东西) 但是,在编译器报告这个简单的错误之前,如果必须搜索一些隐含在范围内是否可以解决问题.它可能将Ordering [Int] o2转换为Int(不能)或Ordering [Int] o1到具有def<(Ordered [Int])方法的东西,例如Orderered [Intered [Int]].而且它发生的时候,它必须停止搜索,因为它似乎可以无限期地进行一个循环.规则在规范中给出. 107到109(2.9版的规格).然而,停止搜索的规则是悲观的,并且可能会丢弃可能已经成功的搜索行,因此编译器认为它必须报告.实际上,大部分时间在这里,周期是正确的,没有解决办法.这是一个令人惊讶的错误信息.我认为更简单的错误也应该被报告,更突出. 让我给出一些有限的解释,为什么可能有隐含的搜索循环.可能有

implicit def f(implicit a: A): B

这意味着如果你有一个隐含的A,你也有一个隐含的B.所以这样做形成一个图形:A提供B.它比这更复杂,它实际上是一个超图:’implcit def f(隐含a:A,隐式b:B):C’:A和B提供C.

使用泛型,你有一个无限数量的类型和一个无限(超)图,通过子类型变得更复杂(如果你需要一个A,A的任何子类型都可以)添加由协方差/反变换隐含的子类型规则)

该图可能包含循环:要获得A,您可以提供一个B,以获得一个B,您可以提供一个C,获得一个C,您可能只提供一个A.总结如果你提供一个A你得到一个A,这是没用的,那行搜索不得不删除.这不是一个问题,在这种情况下,它是一个实际的循环,并且不存在通过删除可能的解决方案的风险.

但是它可能会更复杂,因为图形是无限的,搜索可能是无限的,没有完全骑自行车.如果你有

implicit def[A](x: X[X[A]]): X[A]

那么如果你寻找X [Int],你可能会寻找X [X [Int]],但是使用相同的规则,你可以查找X [X [X [Int]]]等等.它不是完全循环的,但是编译器不追求这些行并且将其称为分歧.除了在隐含范围内可能会有一个隐含的X [X [X … X [Int]]]]]可以使其成功的地方.这就是为什么编译器报告说这一行的探索被删除了.

(编辑:李大同)

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

    推荐文章
      热点阅读