Scala中type T和[T]的区别

4

可能是重复问题:
Scala:抽象类型与泛型

我理解的方式是,以下两个类定义是相同的。那么除了语法之外,还有什么区别呢?

abstract class Container[T] {}
class IntContainer extends Container[Int] {}

abstract class Container2 { type T }
class IntContainer2 extends Container2 { type T = Int }

当我查看反编译的字节码时,我注意到第一组仍然具有泛型(尽管IntContainer被定义为具有Object类型:public class IntContainer extends Container<Object>)。第二组没有这样的信息。我认为所有泛型类型都已被擦除了...
PS:使用Scala 2.10-M5

这是你尝试的最远程度,还是你已经尝试过实际使用这些 IntContainer 对象了? - Gabe
我在每个超类中添加了一个ArrayBuffer字段,并在每个超类中添加了一个“add”方法,该方法委托给缓冲区,在这两种情况下都按预期工作。尝试添加字符串会在两种情况下失败,显示“类型不匹配;找到:String(“asdf”)需要:Asdf.ic2.T(扩展为)Int”。@Gabe,你的意思是什么?因为我觉得我错过了它。 - John Smith
4
请参阅例如此处此处此处此处此处 - Travis Brown
@TravisBrown 第一、第四和第五个链接是最好的,突出了每个链接的优缺点。谢谢! - John Smith
1个回答

2

我们始终需要记住抽象类型和泛型之间的明显区别:

  • 如果一个类作为通用类型,同一类的多个实例可以具有不同的通用类型
  • 如果一个具体类作为抽象类型,对于给定的Scala类,该类的所有实例(确切地说)都将具有相同的抽象类型。

现在你应该清楚两者可以以不同的方式使用:

  • 泛型主要设计为充当容器的类,或者是业务类,这些类应该对给定的目标执行某些操作。在这种意义上,通用参数允许您在编译时检查类型安全性
  • 抽象类型主要设计为在更高级别上定义行为或属性,并在子类化时进行细化。泛型与继承关系关系很小

从另一个角度看,虽然将GenericClass [T]和T作为参数传递给方法是一种常见功能,但设计一个接收ClassWithAbstractTypeT和classWithAbstractType.T的方法要少得多。事实上,在Scala 2.9中编写这样的方法是被禁止的,除非激活了path-dependent mehods(如果我没有错,在2.10中它们默认是激活的)


1
有趣的是,Martin Odersky声称抽象类型可以做到泛型所能做到的一切,甚至建议在以后的版本中删除泛型(可能在4.0时间框架内)。 - Jörg W Mittag
嗯,完全移除泛型?你能提供更多细节吗? - Eugene Burmako
Martin Odersky在这里提出了建议,尽管没有提到4.x版本:https://groups.google.com/forum/?hl=en&fromgroups#!msg/scala-language/PV4q6O1qIh8/yG4p8PA2Jf8J - John Smith
https://contributors.scala-lang.org/t/scala-3-type-parameters-and-type-members/3472 - Dmytro Mitin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接