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
}
答案 0 :(得分:1)
通常使用new T()
来解决Manifest
的需求。例如,此代码编译:
class ExampleClass[T: Manifest] {
val example: T = manifest[T].erasure.newInstance().asInstanceOf[T]
}
缺点是如果实例化T
的{{1}}没有no-arg构造函数,它将在运行时失败...
关于ExampleClass
,Numeric
等,它们是类型类,是标准库的一部分,而不是语言的一部分。您可以构建自己的类型类。 Ordering
的情况很特殊,因为它确实得到语言的支持来提供隐式对象。