【发布时间】:2018-02-28 18:39:54
【问题描述】:
我被一个生产错误所困扰,我将一个不纯的 0 元函数传递给一个错误地期望一个裸结果类型的类。
def impureFunc(): Future[Any] = ???
case class MyService(impureDependency: Future[Any] /* should have been () => Future[Any] */)
实际上,这使得MyService 立即调用impureFunc 并在程序的生命周期内缓存第一个结果,这导致了一个非常微妙的错误。
通常,类型系统可以防止此类错误,但由于能够在没有参数列表的情况下调用 0 元函数,编译器接受了这个程序。
显然,这是 Scala 的一个“特性”,旨在使代码看起来更干净,但这是一个糟糕的陷阱。有什么办法可以使它成为编译器警告或 linting 错误?换句话说,不赞成implicit method conversion的“空申请”类型?
【问题讨论】:
-
这是避免
Future的原因之一。使用更好的类型,可以暂停副作用,并且可以作为纯值进行操作和组合。选项很多:scalaz Task、monix Task、fs2 Task、cats IO等 -
这无济于事,但您可能想知道 dotty 将删除此转换:dotty.epfl.ch/docs/reference/dropped/auto-apply.html。据我所知,我使用过的所有 linter 工具都没有检查这一点。
-
@JoeK 这真是个好消息 :)
-
相反,
warning: Eta-expansion of zero-argument method values is deprecated. Did you intend to write f()? -
@som-snytt 啊,我看到这是在 2.12 (issues.scala-lang.org/browse/SI-7187) 中添加的。我还在 2.11 上。
标签: scala implicit-conversion code-standards