加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 来自超级特征的隐式参数解析

发布时间:2020-12-16 09:49:41 所属栏目:安全 来源:网络整理
导读:我正在尝试使用隐式参数将依赖项“注入”到我的类中,如下所示: trait Bar { def m:String}object Bar { implicit val objBar = new Bar{ val m = "from object" } }trait FooTrait { def aBar(implicit bar:Bar) = bar def go = { aBar.m }} 这里编译器从Ba
我正在尝试使用隐式参数将依赖项“注入”到我的类中,如下所示:

trait Bar {
    def m:String
}

object Bar {
    implicit val objBar = new Bar{ val m = "from object" } 
}

trait FooTrait { 
    def aBar(implicit bar:Bar) = bar
    def go = { aBar.m }
}

这里编译器从Bar的伴随对象中的隐式val向FooTrait提供隐式参数.这样做:

scala> println((new FooTrait{}).go)
from object

给我我期望的结果.但是,如果我混合FooTrait和另一个特征如:

trait SuperFoo {
    implicit val superBar = new Bar{ val m = "from super" }
}

结果是一样的:

scala> println((new FooTrait with SuperFoo).go)
from object

我认为编译器会在尝试通过检查Bar的伴随对象来解析隐式参数之前查看SuperFoo.这blog post状态:

There are very strict rules for which implicit value is to be applied
to a implicit parameter. A simple way to think about it is that the
“closest” definition will be used. Local scope,enclosing class,
parent class,companion object of the desired type.

我错过了什么或者这是scalas隐含参数的已知限制吗?

解决方法

在FooTrait中定义了对aBar的调用.当此特征编译时,本地范围,封闭类或父类中没有正确的含义.当您稍后混入其他特征时,编译器不会尝试重新发现隐含.所以它只使用来自伴随对象的默认隐式.

如果覆盖方法go,你可以从SuperFoo获得价值:

scala> println((new FooTrait with SuperFoo {override def go = {aBar.m}}).go)
from super

您还可以重新定义类层次结构以获取隐式父级特征:

trait BarHolder { 
    implicit val superBar: Bar
}
trait FooTrait extends BarHolder { 
    def aBar(implicit bar:Bar) = bar
    def go = { aBar.m }
}
trait DefaultFoo extends BarHolder {
    val superBar = implicitly[Bar]
}
trait SuperFoo extends BarHolder {
    val superBar = new Bar{ val m = "from super" }
}

并以这种方式使用它:

scala> println((new FooTrait with DefaultFoo).go)
from object

scala> println((new FooTrait with SuperFoo).go)
from super

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读