Scala中的隐式抽象类构造函数参数和继承

西蒙

我对Scala还是陌生的,一直在尝试学习和理解隐式转换和参数,并且遇到了使我感到困惑的场景。

对于上下文,我正在使用Scaldi在Akka应用程序中进行依赖项注入,并且希望有多个可注入的actor从抽象类继承。我相信我无法使抽象类成为一个特征,恰恰是因为我们需要Injector通过构造函数参数来使隐式可用以利用框架。

展示我所看到的行为的一个非常人为的示例如下:

class SecretSauce {}

abstract class Base(implicit secretSauce: SecretSauce) {}

class Concrete extends Base {}

object Example extends App {
    ... // Setup Actor system, etc, etc
    implicit val secretSauce: SecretSauce = new SecretSauce()
}

我期望一切正常,但是却收到编译错误:

Unspecified value parameter secretSauce.
class Concrete extends Base {
             ^

如果像这样将隐式参数添加到具体类中,则工作正常:

class Concrete(implicit secretSauce: SecretSauce) extends Base {}

我认为我的困惑源于隐式参数的工作方式-在我正在描述的情况下,它们不是子类继承的吗?有人可以使用ELI5在我的示例中发生什么情况,还是可以向我提供可以帮助清除问题的参考文献?

谢谢!

特拉维斯·布朗

确定Scala编译器在哪里寻找隐式值的确切规则有点复杂,但是在大多数情况下,您只需要考虑两个地方隐式值可能来自:

  1. 当前范围。
  2. 任何涉及的类型的伴随对象。

这意味着它将编译:

class SecretSauce {}

object SecretSauce {
  implicit val secretSauce: SecretSauce = new SecretSauce()
}

abstract class Base(implicit secretSauce: SecretSauce) {}

object Example extends App {
  class Concrete extends Base {}
}

或这个:

class SecretSauce {}

abstract class Base(implicit secretSauce: SecretSauce) {}

object Example extends App {
  implicit val secretSauce: SecretSauce = new SecretSauce()

  class Concrete extends Base {}
}

但是,在您的版本中,当编译器到达这一行时:

class Concrete extends Base {}

它会知道它需要找到一个隐含的SecretSauce价值,它会先看看隐含值范围在该行并在未来SecretSauce伴侣的对象(如果存在)。它也找不到,因此拒绝编译您的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章