scala – 隐式转换导致无限递归,但不应该进行类型检查
我正在尝试为一个以Squants Time作为参数的类编写Specs2测试.诀窍是两个工具都定义了一个隐式,它添加了一个名为“秒”的方法,将一个数字转换成它们自己的表示形式(一个案例中为squants.time.Seconds,另一个案例中为org.specs2.time.Duration),不幸的是,错误的似乎优先.
val a = new MyClass(10 seconds) // doesn't build because MyClass wants a Time instead of a Duration 要清楚,我可以通过不依赖于暗示来构建Squants时间来解决这个问题,这不是问题. 我更喜欢implicits所以我决定添加一个隐式转换持续时间到Times: implicit def specsTimeToSquantsTime(t: org.specs2.time.Duration): squants.time.Time = squants.time.Seconds(t.toSeconds) 这让它得到了类型检查,但是当我运行测试时,我得到了一个堆栈溢出并且堆栈跟踪没有很大意义,它说我的隐式转换是在调用自己(这不会出现问题,即使是鉴于以上代码,它仍然是不可能的!): [error] package.TestConversions$.specsTimeToSquantsTime(TestConversions.scala:9) [error] package.TestConversions$.specsTimeToSquantsTime(TestConversions.scala:9) [error] package.TestConversions$.specsTimeToSquantsTime(TestConversions.scala:9) ... 所以我有三个问题:这里发生了什么?有一个更好的方法吗?我可以手动隐藏Int =>持续时间吗? 解决方法
方法toSeconds在Time类中定义:
final class Time private (val value: Double) extends Quantity[Time] { ... def toSeconds = to(Seconds) ... } https://github.com/garyKeorkunian/squants/blob/master/src/main/scala/squants/time/Time.scala 因此,当编译器看到在Duration上调用此方法时 – 它正在搜索适当的隐式和它的specsTimeToSquantsTime,它依次包含Duration.toSeconds,这需要从Duration到Time的隐式转换,依此类推.所以你在运行时得到了无限的递归调用,这在编译器方面是完全正确的,理论上你可以停止这种递归,并且没有通用的方法(见halting problem)来检测它. 您可以在规范中混合使用
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |