2012-07-27 6 views

risposta

14

Non direttamente; il solito modo in cui lo faresti in Scala è con un typeclass.

trait FAble[T] { def doF: String } 
object FAble { 
    implicit val fInt = new FAble[Int] { def doF = "I'm an int" } 
    implicit val fFloat = new FAble[Float] { def doF = "I'm a float" } 
    implicit val fBurger = new FAble[Burger] { def doF = "You want fries?" } 
} 

def f[T](implicit ev: FAble[T]) = ev.doF 
// or 
def f[T: FAble] = implicitly[FAble[T]].doF 

E 'un bel po' più prolisso, ma ha alcuni vantaggi troppo - le istanze implicite possono essere calcolati (usando implicit def s invece di val s), e non ci può essere più di un'istanza per ogni tipo , che ti consente di selezionare il comportamento avendo istanze diverse nello scope in diversi punti del codice.

Il motivo per cui non è possibile farlo in modo C++ è che i generici di Scala non implicano la generazione di codice per i diversi parametri di tipo (@specialized a parte, poiché non fa ciò che si desidera). Quindi non ha senso dire "hey compiler, quando vedi una Int in quella posizione, invece di generare il codice che faresti dal modello generico, usa invece questo codice specifico".

1

Si potrebbe voler esaminare i macro: http://scalamacros.org/. Le macro sono funzioni personalizzate che vengono eseguite durante la compilazione e possono generare dinamicamente codice basato su calcoli in fase di compilazione.

2

Un altro approccio possibile è quello di utilizzare prove:

def f[T](t:T)(implicit ev: T<:<Float) { 

// float version 

} 

def f[T](t:T)(implicit ev: T<:<Int) { 

// int version 

} 

Tuttavia mi sento di raccomandare classi di tipo come una soluzione molto più elegante

Problemi correlati