Scala 2.10 TypeTag usage

前端 未结 4 1839
温柔的废话
温柔的废话 2021-02-04 13:27

I\'m digging new scala reflection api and can\'t figure out why the following snippet doesn\'t work as expected. Given hierarchy (tried to simplify as much as I can):

         


        
4条回答
  •  别跟我提以往
    2021-02-04 13:59

    So I think the key problem here is that you need to match against the type of msg, but its compile-time type is Any (from the PartialFunction declaration). Essentially, you want a different TypeTag for each element in your List[Any]. But since they all have compile-time type of Any by virtue of all being put into the same list, you're not going to get a TypeTag that's any more specific than that.

    I think what you probably want to do is use ClassTag instead of TypeTag:

    trait TF[A] {
      implicit def t: ClassTag[A]
    
      def f: PartialFunction[Any, A] = {
        case msg: A => msg
      }
    }
    
    class TFilter[T: ClassTag] extends TF[T] {
      def t = classTag[T]
    }
    
    case class Foo(x: Int)
    
    val messages = Seq(1, "hello", Foo(1), List(1), List("a"))
    messages collect new TFilter[Foo].f // produces List(Foo(1))
    

    As Ajran points out, just like the Manifest version, you'll have to be aware of all the limitations of runtime types including erasure and boxing issues:

    messages collect new TFilter[List[Int]].f // produces List(List(1), List("a"))
    messages collect new TFilter[Int].f // produces List()
    messages collect new TFilter[java.lang.Integer].f // produces List(1)
    

    There are some suggestions about how to make TypeTag more useful for pattern matching (e.g. SI-6517), but I think those will only help when you're matching against an object with an useful TypeTag, not an object with compile-time type of Any.

提交回复
热议问题