【问题标题】:(In Scala,) Is there anything that can be done with generic type parameters of classes but not with abstract type members?(在 Scala 中)有什么可以用类的泛型类型参数而不是抽象类型成员来完成的吗?
【发布时间】:2014-10-07 10:02:06
【问题描述】:

很明显,不能对具有抽象类型成员的方法进行参数化。但是,除了类型和实例化可以写得更短的便利问题之外,是否存在任何理由的泛型类型参数,例如在以下抽象的 List-ArrayList 场景中:

这里,参数化是通过一个抽象类型成员来实现的:

trait base1 {
    type X
    def id(x: X): X
}
class extension1 extends base1 {
    override def id(x: X): X = x
}
val ext1: base1 { type X = Int } = new extension1 { type X = Int }
val y1 = ext1.id(0)

这里是通过泛型类型参数实现的:

trait base2[X] {
    def id(x: X): X
}
class extension2[X] extends base2[X] {
    override def id(x: X): X = x
}
val ext2: base2[Int] = new extension2[Int]
val y2 = ext2.id(0)

后一种方案更方便、更易读。这本身很重要,但我对更一般的观点感兴趣,即语义

This Martin Odersky 的采访是一个很好的介绍,但它似乎没有回答这个问题。

非常感谢您的任何提示或解释!

【问题讨论】:

  • 对不起。但我不明白确切的问题。你具体问的是什么?

标签: scala generics types parameters abstract


【解决方案1】:

Dean Wampler 和 Alex Payne 所著的Scala 编程一书很好地 overview 介绍了何时使用类型参数和抽象类型成员。

除了不能参数化方法(这可能是一个很大的限制)之外,还有两个抽象类型成员的限制:

  1. 抽象类型不能进行方差注释(参见p. 269)这意味着没有与抽象类型成员等效的trait List[+T]trait Function[-T,+R]

    李>
  2. 抽象类型可能会导致与路径相关的类型出现不合理的类型错误。 p. 272 上有一个例子。

【讨论】:

  • 这是否意味着以下内容:如果抽象类型参数具有差异注释(可能与泛型类型参数之一相同) - 以及不合理的类型错误(我还没有真正理解第 272 页上的示例,因为下一页被空白)将被改进的编译器设计排除 - 没有任何理由使用泛型类型参数? (当然对于类,对于它们相关的方法)
  • @Majakovskij 还要考虑 Java 互操作性。
  • @Majakovskij 类型参数和类型成员部分是多余的。类型参数不那么冗长,但对于大多数现实世界的场景来说仍然足够。如果您需要命名类型,那么抽象类型成员就会发挥作用。 Scala 标准库本身很少使用它们这一事实反映了实例化它们有点尴尬的事实。我实际上认为DOT-CalculusDOTTY 旨在统一它们,这会导致类似命名类型参数的东西!?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 2013-05-05
  • 2021-10-09
  • 1970-01-01
相关资源
最近更新 更多