gpt4 book ai didi

使用设置为 null 的隐式 val 时,Scala 编译器的行为不符合预期

转载 作者:行者123 更新时间:2023-12-04 22:11:19 26 4
gpt4 key购买 nike

我遇到了这种非常奇怪的行为,这让我难倒了很长一段时间。我在下面的一个简单片段中重新创建了它,代码是从 Scala 包装器中提取的。

scala> def a = {
| implicit val u = null
| val x: Int = List(1,2,3).map(_.toString)
| }
a: Unit

在上面的代码中,即使我知道 val x 的类型是 List[String],也没有抛出错误。我可以将 x 的类型更改为 Int、Long 等,它会继续正常编译。

但是,当我为隐式 val u 显式添加一个类型时,就像在下面的示例中一样,编译器会按预期运行并引发错误。
scala> def a = {
| implicit val u: Any = null
| val x: Int = List(1,2,3).map(_.toString)
| }
<console>:10: error: type mismatch;
found : List[String]
required: Int

有没有其他人经历过这种情况或对为什么会发生这种情况有任何见解?

最佳答案

由于 scala 中集合的设计方式,null 被选择为 map 的隐式参数,它具有以下扩展签名:

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That

在这个具体的例子中,隐式参数必须是一个 CanBuildFrom[List[Int], String, Int] ,不幸的是 null 是一个底部类型,所以它满足这样的要求。

检查此 QA 以获取更多详细信息: How does CanBuildFrom know whether a type can build from another?

您可以在没有这样隐含的情况下重现它:
@ def a = {
val x: Int = List(1,2,3).map(_.toString)(null)
}
defined function a

然后,当您实际运行该函数时,它会尝试应用构建器,但它为空,所以... BOOM!
@ a
java.lang.NullPointerException
scala.collection.TraversableLike$class.builder$1(TraversableLike.scala:240)
scala.collection.TraversableLike$class.map(TraversableLike.scala:244)
scala.collection.immutable.List.map(List.scala:285)
cmd3$.a(Main.scala:52)
cmd4$$anonfun$1.apply$mcV$sp(Main.scala:52)
cmd4$.<init>(Main.scala:53)
cmd4$.<clinit>(Main.scala:-1)

您可以在堆栈跟踪中看到,一旦在 TraversableLike 上执行 map 尝试访问 builder ,它恰好是 null ,一切都会中断。

关于使用设置为 null 的隐式 val 时,Scala 编译器的行为不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32124847/

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