我对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编译器在哪里寻找隐式值的确切规则有点复杂,但是在大多数情况下,您只需要考虑两个地方隐式值可能来自:
这意味着它将编译:
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] 删除。
我来说两句