【问题标题】:When can Scala's implicitly return null?Scala什么时候可以隐式返回null?
【发布时间】:2016-06-30 00:46:28
【问题描述】:

最近,当调用 Scala 的 implicitly 在运行时返回 null 时,我感到很惊讶。我认为这不太可能,因为如果隐式范围内没有可用的隐式实例,则代码不应编译。何时允许隐式返回 null?这是编译器限制,还是这是预期的行为?

这里有一些上下文,如果有帮助的话。我正在使用 shapeless 派生类型类实例以持久化任意嵌套案例类。我认为在嵌套案例类中隐式使用来检查是否可以派生类型类实例会很有帮助,因为如果嵌套案例类很大,可能不清楚从哪里开始查找。

因此,例如,如果我试图坚持:

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

【问题讨论】:

  • MyFormatter 相关的代码有问题。 Something 隐含了这一点,但如果没有看到它,就不可能说出什么。 Scala 编译器不会自己神奇地创建一个 null
  • 我听到了你在说什么:但缺少像 implicit val oyVey: MyFormatter[Bar] = null 这样的定义(我保证我没有这样做),是什么让这成为可能?
  • 不看代码不知道。 implicitly 没有魔法。你可以试试println(scala.reflect.runtime.universe.reify(implicitly[MyFormatter[Foo]])) 看看它是从哪里解决的。

标签: scala typeclass implicit shapeless


【解决方案1】:

您的隐式定义是递归的。

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

另外,最好指定隐含的类型;有时有必要进行推理;总有一天它会被需要。

【讨论】:

    猜你喜欢
    • 2015-02-10
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2014-07-06
    相关资源
    最近更新 更多