【问题标题】:How to avoid duplication of type constraint in scala如何避免scala中类型约束的重复
【发布时间】:2018-03-19 22:34:09
【问题描述】:

我在 Scala 中经常遇到以下问题:

给定一个特征

trait Foo { def foo: String }

和一个参数化的类

case class Bar[T <: Foo](t: T)

我想编写一个与 Bar 一起工作的方法,而不需要复制类型约束,例如:

def doSth(bar: Bar[_]) = bar.t.foo

不幸的是,它没有编译,我需要写:

def doSth[T <: Foo](bar: Bar[T]) = bar.t.foo

为什么编译器不能推断如果我有一个Bar[_],那么_ 必须是一个Foo

是否有解决方法(抽象类型会避免重复,但会增加表示某些约束的复杂性)?

【问题讨论】:

    标签: scala types


    【解决方案1】:

    好像

    def doSth(bar: Bar[_]) = bar.t.foo
    

    本质上是一样的

    def doSth0(bar: Bar[X] forSome { type X }) = bar.t.foo
    

    type X 完全不受约束。因此,在我看来,问题应该是:

    为什么编译器完全允许Bar[X] forSome { type X } 之类的东西,即使X 没有声明为Foo 的子类型,而Bar 要求参数是Foo 的子类型?

    我不知道答案。可能它又与 java 泛型有关。


    解决方法

    鉴于特质和阶级

    trait Foo { def foo: String }
    case class Bar[T <: Foo](t: T)
    

    以下两个定义无需额外的类型参数即可工作:

    def doSth1(bar: Bar[X] forSome { type X <: Foo }) = bar.t.foo
    def doSth2(bar: Bar[_ <: Foo]) = bar.t.foo
    

    另一种选择是在Bar 本身中限制t 的类型:

    case class Bar2[T <: Foo](t: T with Foo)
    def doSth3(bar: Bar2[_]) = bar.t.foo
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2020-09-17
      • 2012-08-21
      • 2020-01-04
      • 2019-07-30
      • 1970-01-01
      相关资源
      最近更新 更多