gpt4 book ai didi

scala - 为什么这个简单的隐式 stringToInt 函数会导致堆栈溢出?

转载 作者:行者123 更新时间:2023-12-04 17:35:36 24 4
gpt4 key购买 nike

如果我定义一个简单的 stringToInt 函数并将其存储为 val,则一切都按预期工作,例如

scala> def stringToInt1: (String => Int) = _.toInt
stringToInt1: String => Int

scala> stringToInt1("1")
res0: Int = 1

但是,如果我将其隐式化,则会导致堆栈溢出:
scala> implicit def stringToInt2: (String => Int) = _.toInt
stringToInt2: String => Int

scala> stringToInt2("1")
java.lang.StackOverflowError
at .stringToInt2(<console>:7)
at $anonfun$stringToInt2$1.apply(<console>:7)
at $anonfun$stringToInt2$1.apply(<console>:7)
...

起初我怀疑这是因为下划线没有按照我的预期解析,但事实并非如此,因为这种隐式 val 样式适用于以下简单函数:
scala> implicit def plusTwo: (Int => Int) = _ + 2
plusTwo: Int => Int

scala> plusTwo(2)
res2: Int = 4

如果我明确定义参数,则不会出现堆栈溢出:
scala> implicit def stringToInt3(s: String) = s.toInt
stringToInt3: (s: String)Int

scala> stringToInt3("1")
res3: Int = 1

(如果您自己尝试并且最后一个案例堆栈溢出,请重新启动 Scala 控制台并重做最后一步)

所以我的问题是,为什么原始的隐式没有正确解析?

编辑

好的,在这里深入一点,似乎问题在于从 String 到 StringOps 的隐式转换。如果我们去掉它,它工作正常:
scala> import scala.collection.immutable.StringOps
import scala.collection.immutable.StringOps

scala> implicit def stringToInt4: (String => Int) = new StringOps(_).toInt
stringToInt4: String => Int

scala> stringToInt4("1")
res4: Int = 1

但为什么隐式转换会导致问题?

最佳答案

补充其他回复。

toInt方法在 String . Scala 必须找到一个隐式转换,该转换将产生具有 toInt 的类型。方法。

通常是 StringOps转换提供此 toInt .
然而Int toInt同样,所以 Scala 会从 String => Int 找到您的转换并决定它优先于 StringOps转换,从而递归地应用它。

这就是为什么StringToInt4有效,因为您明确告诉编译器您想要什么转换。也许你可以把它写成:implicit def stringToInt5: (StringOps => Int) = _.toInt或检查隐式如何解决以及一个如何优先于另一个。

关于scala - 为什么这个简单的隐式 stringToInt 函数会导致堆栈溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20541189/

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