2011-02-01 21 views
5

Proszę wskazać mi poprawny link, jeśli wcześniej udzielono na nie odpowiedzi.Czy możemy dopasować Dowolny do rodzaju ogólnego? [Scala 2.8]

mam ten kod:

def getResult(a:Any):Any = a 

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

To daje mi unchecked warning i wszystko pasuje do T. Na przykład, gdy wykonuję getAnswer[Int](2), otrzymuję Some(2) (zgodnie z oczekiwaniami). Jednakże, jeśli wykonam getAnswer[String](2), otrzymam również Some(2), którego się nie spodziewam (potrzebuję None).

Czy istnieje sposób obejścia wymazywania typu i jakoś uzyskać poprawne działanie getAnswer (tzn. Powrócić Some(result) wtedy i tylko wtedy, gdy wynik jest typu T)?

Z góry dziękuję.

Odpowiedz

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 
} 

Jak pisał Alexey, masz jakieś problemy z prymitywów. Technika stosowana w źródłach Scala w takich przypadkach obejmuje zawsze osobne dopasowania dla każdego typu pierwotnego, więc domyślam się, że nie ma możliwości obejścia.

+0

Dziękujemy za odpowiedź na temat obsługi prymitywów. Odpowiedź Alexey'a jest również dobra. – Jus12

+0

Wybrałem odpowiedź jako poprawną, ponieważ obsługuje ona typy pierwotne. Jeszcze raz, dzięki za kod. – Jus12

5

Działa to z pewnymi ograniczeniami (T musi być klasą, a nie typem pierwotnym, jeśli T jest ogólne, parametry są ignorowane).

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

Musimy zmodyfikować 'getResult', aby również zwrócić' AnyRef'. W moim przypadku 'T' jest zawsze klasą lub obiektem i nigdy nie jest typem pierwotnym, więc może to dla mnie działać. Sprawdzę i powrócę. – Jus12