ฉันกำลังขุด API การสะท้อนสกาล่าใหม่และไม่เข้าใจว่าทำไมตัวอย่างต่อไปนี้จึงไม่ทำงานตามที่คาดไว้ กำหนดลำดับชั้น (พยายามลดความซับซ้อนให้มากที่สุด):
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
ผิดหรือเป็นข้อบกพร่องของ Reflection 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
แบบเก่า - person Steve   schedule 05.11.2012