2013-06-02 43 views
4

有沒有一種方法可以用泛型來概括此代碼?針對不同類型的列表的通用不應用方法

object ListInt { 
    def unapply(o: Any): Option[List[Int]] = o match { 
    case lst: List[_] if(lst.forall(_.isInstanceOf[Int])) => 
     Some(lst.asInstanceOf[List[Int]]) 
    case _ => None 
    } 
} 
object ListDouble { 
    def unapply(o: Any): Option[List[Double]] = o match { 
    case lst: List[_] if(lst.forall(_.isInstanceOf[Double])) => 
     Some(lst.asInstanceOf[List[Double]]) 
    case _ => None 
    } 
} 
object ListString { 
    def unapply(o: Any): Option[List[String]] = o match { 
    case lst: List[_] if(lst.forall(_.isInstanceOf[String])) => 
     Some(lst.asInstanceOf[List[String]]) 
    case _ => None 
    } 
} 

val o: Any = List("a", "b", "c") 
o match { 
    case ListInt(lst) => println(lst.sum) 
    case ListDouble(lst) => println(lst.product) 
    case ListString(lst) => println(lst.mkString("(", ", ", ")")) 
    case _ => println("no match") 
} 
+0

也許這個問題:HTTP:// stackoverflow.com/questions/4529562/pattern-match-on-a-generic-type和答案可以幫助。 –

+0

你覺得你的'match'子句看起來像什麼? –

回答

6
abstract class ListExtractor[A](implicit ct: reflect.ClassTag[A]) { 
    def unapply(o: Any): Option[List[A]] = o match { 
    case lst: List[_] if (lst.forall(ct.unapply(_).isDefined)) => 
     Some(lst.asInstanceOf[List[A]]) 
    case _ => None 
    } 
} 

object ListInt extends ListExtractor[Int ] 
object ListString extends ListExtractor[String] 

val o: Any = List("a", "b", "c") 
o match { 
    case ListInt (lst) => println(lst.sum) 
    case ListString(lst) => println(lst.mkString("(", ", ", ")")) 
    case _    => println("no match") 
} 
3

看來TypeTag是要走的路:

import scala.reflect.runtime.universe._ 

def foo[A: TypeTag](lst: A) = typeOf[A] match { 
    case t if t =:= typeOf[List[Int]] => lst.asInstanceOf[List[Int]].sum 
    case t if t =:= typeOf[List[Double]] => lst.asInstanceOf[List[Double]].product 
    case t if t =:= typeOf[List[String]] => lst.asInstanceOf[List[String]].mkString("(", ", ", ")") 
} 

println(foo(List("a", "b", "c"))) 

檢查這個優秀的職位詳細說明:

Scala: What is a TypeTag and how do I use it?

+0

但是,'List [Any](1,2,3)'不會產生'List [Int]'這種方式。我不知道OP是否需要這樣做? –

+0

那麼,我實際上需要能夠匹配任何類型的數據,但這兩種解決方案都非常有用。 – SpiderPig

+0

@ 0__感謝您指出,我想避免在列表中循環,但似乎沒有簡單的方法。 – Blezz