Scala 什么时候可以隐式 return null?
When can Scala's implicitly return null?
我最近对 Scala 的 implicitly
的调用在运行时 returning null 感到惊讶。我曾认为这不太可能,因为如果隐式范围内没有可用的隐式实例,则代码不应编译。什么时候隐式允许 return null?这是编译器限制,还是预期行为?
这里有一些背景信息,如果有帮助的话。我正在使用 shapeless 派生 typeclass 实例来持久化任意嵌套案例 classes。我认为在嵌套案例 classes 中隐式使用来检查是否可以派生类型 class 实例会很有帮助,因为如果嵌套案例 [=29] 可能不清楚从哪里开始查找=] 很大。
所以,例如,如果我试图坚持:
case class Foo(bar: Bar, baz: Baz)
并且编译器无法为我的格式化程序派生实例 MyFormatter[Foo]
,我开始执行如下操作:
case class Bar(i: Int, q: Qux)
object Bar {
implicit val formatter = implicitly[MyFormatter[Bar]]
}
期待编译器告诉我它找不到 MyFormatter[Bar]
.
的隐式实例
相反,这是一个糟糕的想法,我的代码编译了(当它不应该编译时,因为无法派生 Qux 的类型 class 实例)并且 Bar.formatter
在运行时为 null .
您的隐式定义是递归的。
scala> class C ; object C { implicit val cs: List[C] = implicitly[List[C]] }
defined class C
defined object C
scala> C.cs
res0: List[C] = null
不仅 cs 在范围内,而且对象 C 在 List[C] 的隐式范围内。
此外,最好指定隐含的类型;有时需要推理才能起作用;总有一天会需要它。
我最近对 Scala 的 implicitly
的调用在运行时 returning null 感到惊讶。我曾认为这不太可能,因为如果隐式范围内没有可用的隐式实例,则代码不应编译。什么时候隐式允许 return null?这是编译器限制,还是预期行为?
这里有一些背景信息,如果有帮助的话。我正在使用 shapeless 派生 typeclass 实例来持久化任意嵌套案例 classes。我认为在嵌套案例 classes 中隐式使用来检查是否可以派生类型 class 实例会很有帮助,因为如果嵌套案例 [=29] 可能不清楚从哪里开始查找=] 很大。
所以,例如,如果我试图坚持:
case class Foo(bar: Bar, baz: Baz)
并且编译器无法为我的格式化程序派生实例 MyFormatter[Foo]
,我开始执行如下操作:
case class Bar(i: Int, q: Qux)
object Bar {
implicit val formatter = implicitly[MyFormatter[Bar]]
}
期待编译器告诉我它找不到 MyFormatter[Bar]
.
相反,这是一个糟糕的想法,我的代码编译了(当它不应该编译时,因为无法派生 Qux 的类型 class 实例)并且 Bar.formatter
在运行时为 null .
您的隐式定义是递归的。
scala> class C ; object C { implicit val cs: List[C] = implicitly[List[C]] }
defined class C
defined object C
scala> C.cs
res0: List[C] = null
不仅 cs 在范围内,而且对象 C 在 List[C] 的隐式范围内。
此外,最好指定隐含的类型;有时需要推理才能起作用;总有一天会需要它。