scala - 在Scala中创建类型的新实例

标签 scala types

如果我有C类定义为

class C[A]

有什么办法可以在C中创建A的新实例?就像是
class C[A] {
  def f(): A = new A()
}

我知道,如果可能的话,您可能必须在某个地方指定构造函数参数,这很好。

如果不可能,是否有任何设计模式可用于处理您要创建类型的新实例的情况?

最佳答案

您可以使用类型类来抽象化实例化:

trait Makeable[T] {
   def make: T
}

class C[T: Makeable] {
   def f(): T = implicitly[Makeable[T]].make
}

例如,
implicit object StringIsMakeable extends Makeable[String] {
   def make: String = "a string"
}

val c = new C[String]
c.f // == "a string"

实例化C时,您需要显式或隐式提供一个Makeable,它将用作适当类型的工厂。当然,该工厂将负责在调用构造函数时提供任何构造函数参数。

另外,您可以使用 list ,但是要警告该方法依赖反射,并且类型不安全:
class C[T: Manifest] {
   def f(): T = manifest[T].erasure.newInstance.asInstanceOf[T]
}

为了完整起见,您还可以轻松扩展此方法,以将一些或所有构造函数参数传递给make方法:
trait Makeable[Args, T] { def make(a: Args): T }

class C[Args, T](implicit e: Makeable[Args, T]) {
   def f(a: Args): T = e.make(a)
}

// some examples
case class Person(firstName: String, lastName: String)

implicit val personFactory1 = new Makeable[(String, String), Person] {
   def make(a: (String, String)): Person = Person(a._1, a._2)
}
implicit val personFactory2 = new Makeable[String, Person] {
   def make(a: String): Person = Person(a, "Smith")
}

val c1 = new C[String, Person]
c1.f("Joe") // returns Person("Joe", "Smith")

val c2 = new C[(String, String), Person]
c2.f("John", "Smith") // returns Person("John", "Smith")

关于scala - 在Scala中创建类型的新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5302687/

相关文章:

Scala Play/SBT 更改解析器的顺序

java - 使用Scala获取底层的JSON数据

scala - Scala宏:使用Scala中的类的字段制作 map

scala - 为什么 PersistentActor 的方法 persist 不返回 Future?

optimization - Scala "primitive"优化

Swift 类型转换和括号

c# - 如何在 C# 中查找对象类型?

函数类型的 Scala 类型推断

go - 为 switch 中的类型实现逻辑或

haskell - Haskell中不同类型的乘法