Обход типа стирания: проблема с типом черты! - PullRequest
2 голосов
/ 16 марта 2011

Я хочу обойти стирание типов в случае совпадения, используя код из здесь :

 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]                   ^

Как получить требуемый тип в манифесте или как изменить код, чтобы он работал без ошибок или предупреждений?!

Спасибо за любую помощь

1 Ответ

1 голос
/ 16 марта 2011

Вам нужно Manifest для типа T.Если бы вы объявили класс вместо черты, сработало бы следующее:

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]
}
...