`trait ValueHolder {type ValueType}`和`trait ValueHolder [T] {}之间有什么区别?

时间:2013-07-11 06:26:26

标签: scala generics lift traits

当我阅读Liftweb的源代码时,我发现了一些特征声明:

trait ValueHolder {
  type ValueType
  def get: ValueType
}

trait PValueHolder[T] extends ValueHolder {
  type ValueType = T
}

我的问题是,对于以下两个特征声明:

trait ValueHolder {
    type ValueType
}

trait ValueHolder[T] {
}

我认为他们彼此相同,但他们之间有什么区别吗?一个人可以做或提供另一个人不能做的事吗?

1 个答案:

答案 0 :(得分:6)

第一个叫做abstract type member,第二个叫做Java泛型,但不完全相同。这是实现相同目标的两种不同方式。正如Martin Odersky所解释的那样his采访,同时具有抽象类型成员和泛型类型参数的一个原因是正交性:

  

总有两种抽象概念:参数化   和抽象的成员。在Java中你也有两者,但它取决于   你在抽象的东西。在Java中,您有抽象方法,但是   您不能将方法作为参数传递。你没有抽象   字段,但您可以将值作为参数传递。和你一样   没有抽象类型成员,但您可以将类型指定为   参数。所以在Java中你也有这三个,但有一个   区分你可以用什么抽象原则   各种各样的事情。你可以说这种区别是公平的   任意的。

     

我们在Scala中所做的是尝试更完整和正交。我们   决定对所有三种类型都有相同的构造原则   成员。所以你可以有抽象的字段和价值   参数。您可以将方法(或“函数”)作为参数传递,或者   你可以抽象出来。您可以将类型指定为参数,或   你可以抽象出来。我们从概念上得到的是我们   可以用另一个来模拟一个。至少在原则上,我们可以   将各种参数化表达为面向对象的一种形式   抽象。所以在某种意义上你可以说Scala更正交   和完整的语言。

他还描述了抽象类型成员和通用类型参数之间的区别,这些参数可以在实践中显示出来:

  

但实际上,当你使用很多类型参数化时   不同的东西,它会导致参数爆炸,通常,   更重要的是,在参数范围内。在1998年的ECOOP,Kim Bruce,   Phil Wadler和我有一篇论文,我们展示了随着你的增加   你不知道的事情数量,典型的程序会增长   二次。所以有很好的理由不做参数,   但要拥有这些抽象成员,因为他们不会给你这个   二次爆炸。

我认为比尔维纳斯(ScalaTest的创建者)given是一个很好的例子:

// Type parameter version
trait FixtureSuite[F] {
  // ...
}

// Type member version
trait FixtureSuite {
  type F
  // ...
}

在任何一种情况下,F都是要传递给测试的fixture参数的类型,哪些套件子类将具体化。下面是一个具体测试套件的示例,需要使用类型参数方法将StringBuilder传递到每个测试中:

// Type parameter version
class MySuite extends FixtureSuite[StringBuilder] {
  // ...
}

这是一个具体测试套件的示例,需要使用抽象类型成员方法将StringBuilder传递到每个测试中:

// Type member version
class MySuite extends FixtureSuite {
  type F = StringBuilder
  // ...
}

例如,如果要将三个不同的fixture对象传递给测试,您将能够这样做,但是您需要指定三种类型,每个参数一个。因此选择了类型参数方法,您的套件类可能最终看起来像这样:

// Type parameter version
class MySuite extends FixtureSuite3[StringBuilder, ListBuffer, Stack] with MyHandyFixture {
  // ...
}

而使用类型成员方法,它将如下所示:

// Type member version
class MySuite extends FixtureSuite3 with MyHandyFixture {
  // ...
}

因此,这显示了实现优秀模块化抽象的两个目标。有关此主题的更多信息,请参阅this关于可扩展组件的传奇文章

相关问题