【发布时间】:2017-03-12 00:39:24
【问题描述】:
我有一个特点:
trait Crawler {
implicit def system: ActorSystem
implicit def executionContext: ExecutionContext
implicit def materializer: Materializer
// other methods
}
还有一个测试类:
class CrawlerSpec extends AsyncFlatSpec with Matchers with Crawler {
override implicit val system: ActorSystem = ActorSystem("ufo-sightings")
override implicit val executionContext: ExecutionContext = implicitly[ExecutionContext]
override implicit val materializer: Materializer = ActorMaterializer()
// test
}
根据 Scalatest doc:
异步风格特征扩展了 AsyncTestSuite,它提供了一个 隐式 scala.concurrent.ExecutionContext 命名为 executionContext。
但是由于ExecutionContext 为空,测试因 NPE 而失败(应该正常失败,但这是另一回事)。
java.lang.NullPointerException was thrown.
java.lang.NullPointerException
at scala.concurrent.impl.Future$.apply(Future.scala:31)
at scala.concurrent.Future$.apply(Future.scala:494)
为什么隐含的ExecutionContext 没有被拾取?
<rant>
Implicit resolution is a nightmare. At the expense of saving a few
keystrokes, it makes code so fragile that removal of a single
import breaks it. There's a reason other statically typed languages like
Haskell or Kotlin don't have it; it's a stinking mess.
</rant>
【问题讨论】:
-
把隐式关键字从类和特征中去掉,看是否编译。
-
@pedrofurla 不会,特征中的方法需要隐式 ec。
-
你知道这如何回答你的问题吗?
-
我认为这种咆哮有点不必要。隐式是为提供类型类而创建的,并允许诸如类型类派生和类型级编程之类的东西。据我所知,它们通常不用于普通的依赖注入和传递东西,尽管手动参数在 Scala 世界中仍然是一回事。但是,我同意它们经常被解释得很差,有时被过度使用,并且由于
implicit关键字(隐含的def,val,class,论点是略有不同的野兽)做了不止一件事,它们可能是让刚接触这个概念的人感到困惑。 -
@MateuszKubuszok 据我所知,没有什么能阻止一个人从另一种类型显式转换。无论如何,这不是这个问题的重点,所以我把它留在这里。
标签: scala implicit-conversion implicit scalatest