【发布时间】:2012-10-25 09:13:41
【问题描述】:
我正在挖掘新的 scala 反射 api,但无法弄清楚为什么以下 sn-p 不能按预期工作。给定层次结构(尽量简化):
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 过滤给定类型的对象。所以下面的 sn-p 应该返回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 将按预期返回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方法时,我看不到此警告。 -
@som-snytt,想想,它正在深入研究。缺乏英语练习。下次我会更加小心:)
标签: scala reflection scala-2.10