Come si fa notare, C++ ha modelli. In breve, il C++ dice "esiste un test per tutti i tipi T tale che compaia il test". Ciò semplifica implicitamente l'aggiunta di vincoli su T, ma dal lato negativo sono impliciti e potrebbero essere difficili da comprendere per un utente della classe senza leggere il codice.
Il polimorfismo parametrico di Scala (ovvero generici) funziona molto più come ML, Haskell, Java e C#. In Scala, quando scrivi "class Test [T]" stai dicendo "per tutti i T esiste un tipo Test [T]" senza vincoli. È più semplice ragionare formalmente, ma vuol dire che devi essere esplicito riguardo ai vincoli. Ad esempio, in Scala puoi dire "class Test [T <: Foo]" per dire che T deve essere un sottotipo di Foo.
C# ha un modo per aggiungere un vincolo a T riguardante i costruttori, ma sfortunatamente Scala no.
Ci sono un paio di modi per risolvere il tuo problema in Scala. Uno è dattiloscritto ma un bt più dettagliato. L'altro non è typesafe.
Il modo typesafe sembra
class Test[T](implicit val factory :() => T) {
val testVal = factory
}
Poi si può avere un corpo di fabbriche per i tipi di utili nel vostro sistema
object Factories {
implicit def listfact[X]() = List[X]()
implicit def setfact[X]() = Set[X]()
// etc
}
import Factories._
val t = new Test[Set[String]]
Se gli utenti della vostra biblioteca hanno bisogno le loro fabbriche poi si possono aggiungere il proprio equivalente dell'oggetto Factories. Un vantaggio di questa soluzione è che qualsiasi cosa con una fabbrica può essere utilizzata, indipendentemente dal fatto che ci sia o meno un costruttore no-arg.
Il modo non-così-typesafe utilizza la riflessione e una caratteristica in Scala chiamato manifesti che sono un modo per aggirare un vincolo di Java per quanto riguarda la cancellazione di tipo
class Test[T](implicit m : Manifest[T]) {
val testVal = m.erasure.newInstance().asInstanceOf[T]
}
Con questa versione è ancora scrivere
class Foo
val t = new Test[Foo]
Tuttavia, se non c'è nessun costruttore no-arg disponibili si ottiene un'eccezione di runtime invece di un errore di tipo statico
scala> new Test[Set[String]]
java.lang.InstantiationException: scala.collection.immutable.Set
at java.lang.Class.newInstance0(Class.java:340)
Che cos'è una domanda? – stepancheg
Come posso fare questo lavoro? – bsdfish