gpt4 book ai didi

scala - 为什么这些隐式转换会导致循环代码

转载 作者:行者123 更新时间:2023-12-04 10:20:34 24 4
gpt4 key购买 nike

考虑以下 Scala 代码:

object Test {
class A {}

class B extends A {}

class AI extends A {
def sayHello: String = "Hello from AI"
}

implicit def AtoAI(a: A): AI = a

class BI extends B {
def sayHello: String = "Hello from BI"
}

implicit def BtoBI(b: B): BI = b

def main(args: Array[String]) {
val a = new A
println(a.sayHello)

val b = new B
println(b.sayHello)
}
}

隐式的使用会导致代码循环。事实上,反汇编显示,生成的转换方法只有一个 goto 0里面:
public Test$AI AtoAI(Test$A);
Code:
0: goto 0

public Test$BI BtoBI(Test$B);
Code:
0: goto 0

是什么导致了这种行为?我明白,这里的类层次结构是可疑的,但隐式转换应该只应用一次。

我使用 Scala 2.9.1

最佳答案

不好,但我绝对不会称其为错误。

它归结为

class A

class B

implicit def aToB(a: A) : B = a

转换的两个方面不需要以任何方式相关。隐含和写作是一回事
implicit def aToB(a: A): B = aToB(a)

因为编译器插入了 aToB调用以转换结果 a到所需的返回类型 B .
goto 0实现只是尾调用优化。编译器可能会在生成以这种方式启动的方法时发出警告。

也许可能存在一条规则,即隐式方法不能作为隐式方法在它们自己的体内使用。但它并不总是会造成无限循环
implicit def listAToListB(l: list[A] = l match {
case Nil => Nil
case x:xs => toB(x) :: xs // equivalent to toB(x) :: listAToList[B](xs)
}

(好吧,这只是一个 map(toB) )。无论如何,两个相互递归的隐式也可能发生同样的情况。在我看来,仅仅为了避免编写无限循环、无操作循环等的可能性而调整规范是不值得的。但是当检测到这样的循环时发出警告,不管隐式,都会很好。

关于scala - 为什么这些隐式转换会导致循环代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8849491/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com