繁体   English   中英

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

[英]Implicit abstract class constructor parameter and inheritance in 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编译器查找implicits的确切规则有点复杂,但在大多数情况下,您只需要考虑隐含值可能来自的两个位置:

  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同伴对象(如果存在)。 它也找不到,所以它拒绝编译你的代码。

隐式参数从“解析”得出:

  • 当前范围中定义的隐含
  • 明确的进口
  • 通配符导入

据我所知,为了定义class Concrete ,需要定义或导入隐式。

我在这个答案中找到了一个非常好的解释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM