2011-02-01 10 views
5

Indicare per favore di correggere il collegamento se questo è stato risolto prima.Possiamo abbinare Qualsiasi a un tipo generico? [Scala 2.8]

ho questo codice:

def getResult(a:Any):Any = a 

def getAnswer[T](i:Int) = { 
    val result = getResult(i) 
    result match { 
    case t:T => Some(t) 
    case _ => None 
    } 
} 

Questo mi dà una unchecked warning e tutto ciò corrisponde a T. Ad esempio, quando faccio lo getAnswer[Int](2), ottengo Some(2) (come previsto). Tuttavia, se faccio getAnswer[String](2), ottengo anche Some(2) che non è previsto (ho bisogno di None).

C'è un modo per aggirare la cancellazione di tipo e in qualche modo arrivare getAnswer per funzionare correttamente (vale a dire, tornare Some(result) se e solo se il risultato è di tipo T)?

Grazie in anticipo.

risposta

7
def getAnswer[T](i:Any)(implicit m:Manifest[T]) = i match { 
    case t:Int if m.erasure == classOf[Int] => Some(t) 
    case t:Double if m.erasure == classOf[Double] => Some(t) 
    //... other Primitives 
    case t if m.erasure.isInstance(t) => Some(t) //this matches AnyRefs 
    case _ => None 
} 

Come ha scritto Alexey, avete qualche problema con primitive. La tecnica usata nelle fonti di Scala in questi casi comporta sempre corrispondenze separate per ogni singolo tipo primitivo, quindi credo che non ci sia modo di aggirare.

+0

Grazie per la tua risposta su come gestire le primitive. Anche la risposta di Alexey è buona. – Jus12

+0

Ho selezionato la risposta corretta perché è in grado di gestire i tipi primitivi. Ancora una volta, grazie per il codice. – Jus12

5

Questo funziona con alcune limitazioni (T deve essere un tipo di classe e non un tipo primitivo, se T è generico, i parametri vengono ignorati).

def getAnswer[T](i:AnyRef)(implicit m:ClassManifest[T]) = { 
    val result = getResult(i) 
    if (result.getClass == m.erasure) Some(result.asInstanceOf[T]) else None 
} 

> getAnswer[java.lang.Integer](2.asInstanceOf[AnyRef]) 
res4: Option[java.lang.Integer] = Some(2) 

getAnswer[String](2.asInstanceOf[AnyRef]) 
res1: Option[String] = None 
+0

Abbiamo bisogno di modificare 'getResult' per restituire anche' AnyRef'. Nel mio caso, 'T' è sempre una classe o un oggetto e mai un tipo primitivo, quindi potrebbe funzionare solo per me. Controllerò e ripristinerò. – Jus12