2013-02-25 2 views
0

Я пытаюсь сузить общий тип. Он компилируется, но результат не является предполагаемым (Контейнер (A), Контейнер (B) ..) вместо (Контейнер (A), Контейнер (A)). Что я делаю неправильно?Сужение с помощью ClassTag

sealed trait Base 
case class A() extends Base 
case class B() extends Base 
case class Container[+T](item: Base) 


object Test { 
    import scala.reflect.ClassTag 

    def narrowContainer[T <: Base](list: List[Container[Base]])(implicit tag: ClassTag[T]): List[Container[T]] = { 
     list.collect{ case t: Container[T] => t } 
    } 

    def testNarrowContainer(){ 
     val li = List(A(),B(),A(),B()).map(Container(_)) 
     println(narrowContainer[A](li)) 
     println(narrowContainer[B](li)) 
    } 

    def main(args: Array[String]){ 
     testNarrowContainer() 
    } 

} 
+0

Правильный ответ был дан в списке рассылки scala-user от Lars Hupel. Кто-то может опубликовать его здесь. –

ответ

1

В этом выражении T стирается, так что все дело на самом деле проверяет, что t является Container

{ case t: Container[T] => t } 

Я думаю, вы можете добавить охранник явно проверяя содержимое t против tag (извините, не знаю правильного синтаксиса для этого прямо сейчас)

+1

Не совсем. Если в области есть «ClassTag [T]», то новый шаблонный шаблон в 2.10 должен автоматически проверять «T». –