Scala:是否可以将类型参数约束为非抽象?

时间:2012-05-23 19:24:49

标签: scala generics type-bounds

Scala:是否可以将类型参数约束为非抽象的?

除了视图边界,类型参数的上限和下限以及抽象类型成员之外,是否还有其他约束?例如,在我熟悉的C#中,您有其他通用约束:

其中T:Class //不确定Scala是否包含T&lt ;: AnyRef

其中T:interface

其中T:struct

其中U:T //裸体类型约束

其中T:new()//这确保了一个类型参数是非抽象的,并允许一个实例化泛型类中该类型的对象。

最后一个特别重要,因为它允许你构造你的未知类型,虽然很遗憾你只能禁止无参数构造函数。

Can =:=<:<和<%<仅用于方法参数?

在回应评论时,问题的直接触发因素是需要“T:new()”克制或某种等效机制。

class ExampleClass[T <: AnyRef] {
  val example: T = new T()//Won't compile as the compiler  
} //doesn't know if such a constructor exists

某些C#约束的使用特别适合C#的需求。例如,人们一直想要的C#中没有的一个约束是“T:numericType”这个问题已经在Scala中解决了。我仍然非常喜欢使用Scala语言,所以除了上述内容之外,我只是想在Scala语法的这个方面确切地说明哪些工具是不可用的,即使我不这样做我知道如何在Scala上下文中使用它们。

我不确定这是否完全相关,但有时似乎编译器(带有Eclipse 3.7.2的Eclipse 2.1.0.M1)将不允许我实例化未知元素类型的集合。以下代码现在似乎编译好了。所以我想知道规则是什么:

abstract class Descrip [T <: DTypes]()
{      
  val hexs: MutableList[T#HexT] = new  MutableList[T#HexT] //compiles fine
  val sides: MutableList[T#SideT] = new MutableList[T#SideT] //compiles fine
}

1 个答案:

答案 0 :(得分:1)

通常使用new T()来解决Manifest的需求。例如,此代码编译:

class ExampleClass[T: Manifest] {
  val example: T = manifest[T].erasure.newInstance().asInstanceOf[T]
}

缺点是如果实例化T的{​​{1}}没有no-arg构造函数,它将在运行时失败...

关于ExampleClassNumeric等,它们是类型类,是标准库的一部分,而不是语言的一部分。您可以构建自己的类型类。 Ordering的情况很特殊,因为它确实得到语言的支持来提供隐式对象。