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

F-Bounded多态与Scala中的抽象类型

发布时间:2020-12-16 18:30:20 所属栏目:安全 来源:网络整理
导读:我已经阅读了几篇文章,表示应该使用抽象类型来实现 Scala中的f-bounded多态.这主要是为了缓解类型推断问题,同时也消除了类型参数在定义递归类型时似乎引入的二次增长. 这些定义如下: trait EventSourced[E] { self = type FBound : EventSourced[E] { type
我已经阅读了几篇文章,表示应该使用抽象类型来实现 Scala中的f-bounded多态.这主要是为了缓解类型推断问题,同时也消除了类型参数在定义递归类型时似乎引入的二次增长.

这些定义如下:

trait EventSourced[E] {
  self =>

  type FBound <: EventSourced[E] { type FBound <: self.FBound }

  def apply(event: E): FBound
}

但是,这似乎引入了两个问题:

1)每次用户想要引用此类型的对象时,它们还必须引用FBound类型参数.这感觉就像代码味道:

def mapToSomething[ES <: EventSourced[E],E](eventSourced: ES#FBound): Something[ES,E] = ...

2)编译器现在无法推断上述方法的类型参数,但没有消息:

Type mismatch,expected: NotInferredES#FBound,actual: MyImpl#FBound

是否有人在其解决方案中使用f-bounded多态的成功实现,编译器仍然可以推断类型?

解决方法

我已经意识到在大多数情况下应该避免使用f-bounded多态 – 或者更确切地说 – 通常还有一种你应该选择的替代设计.要了解如何避免它,我们首先需要知道是什么让我们需要它:

F-bounded polymorphism occurs when a type expects important interface changes to be introduced in derived types.

通过编写预期的更改区域而不是尝试通过继承来支持它们来避免这种情况.这实际上回到了Gang of Four设计模式:

Favor ‘object composition’ over ‘class inheritance’

— (Gang of Four,1995)

例如:

trait Vehicle[V <: Vehicle[V,W],W] {
    def replaceWheels(wheels: W): V
}

变为:

trait Vehicle[T,W] {
    val vehicleType: T
    def replaceWheels(wheels: W): Vehicle[T,W]
}

这里,“预期变化”是车辆类型(例如Bike,Car,Lorry).前面的例子假设这将通过继承添加,需要一个f-bounded类型,使得使用Vehicle的任何函数都不可能推断W.使用合成的新方法不会出现此问题.

见:https://github.com/ljwagerfield/scala-type-inference/blob/master/README.md#avoiding-f-bounded-polymorphism

(编辑:李大同)

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

    推荐文章
      热点阅读