Scala 不允许您在类型约束(例如 C#)中指定构造函数的签名。
但是,Scala 确实允许您通过使用类型类模式来实现等效的目标。这更灵活,但需要编写更多样板代码。
首先,定义 atrait
这将是一个用于创建T
给定 an的接口Int
。
trait Factory[T] {
def fromInt(i: Int): T
}
然后,implicit
为您想要的任何类型定义一个实例。假设您有一些class Foo
带有适当的构造函数。
implicit val FooFactory = new Factory[Foo] {
def fromInt(i: Int) = new Foo(i)
}
现在,您可以为以下签名中的类型参数指定上下文绑定:T
Class1
class Class1[T : Factory] {
def method1(i: Int) = {
val instance = implicitly[Factory[T]].fromInt(i)
// ...
}
}
约束T : Factory
说必须有一个隐含Factory[T]
的范围。当您需要使用该实例时,您可以使用该implicitly
方法从隐式范围中获取它。
或者,您可以将工厂指定为需要它的方法的隐式参数。
class Class1[T] {
def method1(i: Int)(implicit factory: Factory[T]) = {
val instance = factory.fromInt(i)
// ...
}
}
这比将约束放在类签名中更灵活,因为这意味着您可以Class1
拥有其他不需要Factory[T]
. Factory[T]
在这种情况下,除非您调用需要它的方法之一,否则编译器不会强制执行它。
为了响应您的更新(使用 abstractcreator
方法),这是一种完全合理的方法,只要您不介意为 each 创建一个子Class1
类型T
。另请注意,T
在您要创建 的实例的任何时候,都需要是具体类型Class1
,因为您需要为抽象方法提供具体实现。
考虑尝试Class1
在另一个泛型方法中创建一个实例。使用类型类模式时,您可以将必要的类型约束扩展到该方法的类型签名,以便编译:
def instantiateClass1[T : Factory] = new Class1[T]
如果您不需要这样做,那么您可能不需要类型类模式的全部功能。