什么时候Scala可以隐式返回null?

时间:2016-06-30 00:46:28

标签: scala typeclass implicit shapeless

当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在运行时为空。

1 个答案:

答案 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]的隐式范围内。

此外,最好指定隐含的类型;有时需要推断工作;有一天它将被要求。