Scala中的抽象类型/类型参数
我正在尝试写一些Scala代码,需要执行以下操作:
class Test[Type] { def main { SomeFunc classOf[Type] val testVal: Type = new Type() } } 它是失败的。我显然不了解Scala通用参数。很明显地,误解是在C中,模板基本上像字符串替换一样,所以新的Type()只要传入的类具有默认构造函数就可以工作。但是,在Scala中,类型是不同类型的对象。 解决方法
你指出,C有模板。总之,C说“有一个测试所有类型T,以便测试编译”。这样就可以轻松地在T上隐式添加约束,但是它们是隐含的,并且对于类的用户而言,可能难以理解,而无需阅读代码。
Scala的参数多态性(又名泛型)的工作更像ML,Haskell,Java和C#。在Scala中,当你写“class Test [T]”时,你说“所有T都存在一个类型Test [T]”,没有约束。这对于正式的理解来说更为简单,但它的确意味着你必须明确约束。例如,在Scala中,您可以说“Class Test [T<:Foo]”来表示T必须是Foo的子类型。 C#有一种方法来向T添加一个关于构造函数的约束,但不幸的是Scala没有。 在Scala中有几种方法可以解决您的问题。一个是类型安全的,但是一个bt更冗长。另一个不是类型安全。 类似安全的方式看起来像 class Test[T](implicit val factory : () => T) { val testVal = factory } 那么你可以有一个工厂的一个类型在您的系统中有用的类型 object Factories { implicit def listfact[X]() = List[X]() implicit def setfact[X]() = Set[X]() // etc } import Factories._ val t = new Test[Set[String]] 如果您的图书馆的用户需要自己的工厂,那么他们可以添加自己等同的工厂对象。这个解决方案的一个优点是可以使用任何一个工厂,无论是否有一个无参数构造函数。 不那么安全的方式使用Scala中的反射和特征,称为清单,这是一种解决Java约束关于类型擦除的方法 class Test[T](implicit m : Manifest[T]) { val testVal = m.erasure.newInstance().asInstanceOf[T] } 有了这个版本,你仍然写 class Foo val t = new Test[Foo] 但是,如果没有no-arg构造函数可用,则会得到运行时异常而不是静态类型错误 scala> new Test[Set[String]] java.lang.InstantiationException: scala.collection.immutable.Set at java.lang.Class.newInstance0(Class.java:340) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |