Я копаю новый API отражения scala и не могу понять, почему следующий фрагмент не работает должным образом. Учитывая иерархию (постарался максимально упростить):
import scala.reflect.runtime.universe._
trait TF[A] {
implicit def t: TypeTag[A]
def f[T <: A: TypeTag]: PartialFunction[Any, A] = {
case msg: T if typeOf[T] =:= typeOf[A] => msg
}
}
class TFilter[T: TypeTag] extends TF[T] {
def t = typeTag[T]
}
case class Foo(x: Int)
Я ожидаю, что метод f
будет фильтровать объекты данного типа. Таким образом, следующий фрагмент должен вернуть Seq[Foo]
val messages = Seq(1, "hello", Foo(1))
val tFilter = new TFilter[Foo]
messages collect tFilter.f[Foo]
И на самом деле он возвращает Seq[Foo]
, но с другими неотфильтрованными сообщениями, что звучит как ошибка.
res1: Seq[Foo] = List(1, hello, Foo(1))
Вопрос. Я неправильно использую TypeTag
или это дефект нового API отражения?
PS0. Пробовал с Scala 2.10.0-RC1
и 2.10.0-RC2
PS1. Обходной путь состоит в том, чтобы заменить TypeTag
на Manifest
, поэтому следующий код collect
on sequence вернет List(Foo(1))
, как и ожидалось.
trait MF[A] {
implicit def m: Manifest[A]
def f[T <: A: Manifest]: PartialFunction[Any, A] = {
case msg: T if typeOf[T] =:= typeOf[A] => msg
}
}
class MFilter[T: Manifest] extends MF[T] {
def m = manifest[T]
}
Обновление: то же самое с новой версией Scala 2.10.0-RC2
.
case msg: T
:warning: abstract type T in type pattern T is unchecked since it is eliminated by erasure
. Я не вижу этого предупреждения со старым подходомManifest
. - person Steve   schedule 05.11.2012