2011-03-16 46 views
2

我想使用的代碼從here繞過類型消除在比賽的情況:避免類型刪除:特質類型的問題!

class Def[C](implicit desired: Manifest[C]) { 

     def unapply[X](c: X)(implicit m: Manifest[X]): Option[C] = { 
      def sameArgs = desired.typeArguments.zip(m.typeArguments).forall { 
      case (desired, actual) => desired >:> actual 
      } 
      if (desired >:> m && sameArgs) Some(c.asInstanceOf[C]) 
      else None 
     } 
} 

此代碼我可以用它來搭配它們通常被擦除的類型。例如:

val IntList = new Def[List[Int]] 
List(1,2,3,4) match { case IntList(l) => l(1) ; case _ => -1 } 

代替:

List(1,2,3,4) match { case l : List[Int] => l(1) ; case _ => -1}//Int is erased! 

,但我得到了與類型系統的一個問題:

trait MyTrait[T]{ 
    type MyInt=Int 
    val BoxOfInt=new Def[Some[MyInt]] // no problem 
    type MyType = T 
    val BoxOfMyType=new Def[Some[MyType]]// could not find.... 
} 

這個問題的結果:

could not find implicit value for parameter desired: Manifest[Some[MyTrait.this.MyType]] 
[INFO] val BoxOfMyType=new Def[Some[MyType]] 
[INFO]     ^

哪有我將所需的類型輸入到Manifest中或者我如何更改代碼以便它在沒有錯誤或警告的情況下運行?

感謝任何幫助

回答

1

您需要的類型T一個Manifest。如果你聲明一個類,而不是一個特徵,下面將工作:

class MyTrait[T : Manifest]{ 
    type MyType = T 
    val BoxOfMyType=new Def[Some[MyType]] 
} 

如果你真的需要一個特質,而不是一個階級,一個替代方法是要求所有子類提供Manifest不知何故,如:

trait MyTrait[T]{ 
    type MyType = T 
    implicit val MyTypeManifest: Manifest[T] 
    val BoxOfMyType=new Def[Some[MyType]] 
} 

class X extends MyTrait[Int] { 
    val MyTypeManifest = manifest[Int] 
} 
+0

您知道,對於隱式清單,您可以使用manifest [T]而不是隱式[Manifest [T]]。 – Anonymous 2011-03-16 13:37:26

+0

好點。建議簡化。 – Steve 2011-03-16 14:04:53