Se puede usar un tipo de clase abstracta a instancias:
trait Makeable[T] {
def make: T
}
class C[T: Makeable] {
def f(): T = implicitly[Makeable[T]].make
}
Por ejemplo,
implicit object StringIsMakeable extends Makeable[String] {
def make: String = "a string"
}
val c = new C[String]
c.f // == "a string"
Al crear una instancia C, se tendrá que proporcionar, explícita o implícitamente, una makeable que actuará como una fábrica del tipo apropiado. Esa fábrica, por supuesto, sería responsable de proporcionar cualquier argumento de constructor cuando invoca al constructor.
Alternativamente, se puede utilizar un manifiesto, pero se advirtió que este enfoque se basa en la reflexión y no es un tipo seguro:
class C[T: Manifest] {
def f(): T = manifest[T].erasure.newInstance.asInstanceOf[T]
}
Para completar, también se puede ampliar fácilmente este enfoque para pasar algunas o todas las los parámetros del constructor en el método de la marca:
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")
Y qué sugieres que sucede si el concreto tipo no tiene un constructor (sin parámetros)? – Raphael
Idealmente, podría especificar esto en el parámetro tipo. Entonces podría definir C como 'clase C [A (String, String)]' o algo así. Entonces tendría que llamar a A con dos argumentos de Cadena. –
¿Es eso válido Scala? – Raphael