当Scala的implicitly
的调用在运行时返回null时,我最近感到很惊讶。我认为这是不可能的,因为如果在隐式范围内没有可用的隐式实例,则代码不应该编译。何时隐式允许返回null?这是编译器限制,还是这种预期的行为?
如果有帮助的话,这里有一些背景信息。我正在使用无形来派生类型类实例来持久化任意嵌套的case类。我认为在嵌套的case类中隐式使用来检查是否可以派生类型类实例是有帮助的,因为可能不清楚从哪里开始查看嵌套的case类是否很大。
所以,例如,如果我试图坚持:
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的类型类实例可以派生)并且Bar.formatter
在运行时为空。
答案 0 :(得分:8)
您的隐式定义是递归的。
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]的隐式范围内。
此外,最好指定隐含的类型;有时需要推断工作;有一天它将被要求。