Scala检查泛型的类型

时间:2014-03-12 03:19:15

标签: scala generics type-inference scala-2.10 type-erasure

如何在Scala中执行此类操作?

case class Foo[A](x: A) {

  def get[T]: Option[T] = x match {
    case x: T => Some(x)    // if x is of type T i.e. T =:= A
    case _ => None
  }
}

val test = Foo("hi")
assert(test.get[Int] == None)
assert(test.get[String] == Some("hi"))

我试过这个并且遇到了一些奇怪的时间推断失败:

import scala.util.{Try, Success}
import reflect._

case class Foo[A](x: A) extends Dynamic {

  def get[T: ClassTag]: Option[T] = Try(x.asInstanceOf[T]) match {
    case Success(r) => Some(r) 
    case _ => None
  }
}

object Foo extends App {
  val test = Foo("hi")
  val wtf: Option[Int] = test.get[Int]
  assert(wtf.isInstanceOf[Option[String]])
  assert(wtf == Some("hi"))     // how????
  // val wtf2: Option[String] = wtf  // does not compile even if above assert passes!!
}

2 个答案:

答案 0 :(得分:2)

当然是一个骗局,但是仓促地说:

scala> :pa
// Entering paste mode (ctrl-D to finish)

import reflect._
case class Foo[A](x: A) {

  def get[T: ClassTag]: Option[T] = x match {
    case x: T => Some(x)    // if x is of type T i.e. T =:= A
    case _ => None
  }
}

// Exiting paste mode, now interpreting.

import reflect._
defined class Foo

scala> val test = Foo("hi")
test: Foo[String] = Foo(hi)

scala> test.get[Int]
res0: Option[Int] = None

scala> test.get[String]
res1: Option[String] = Some(hi)

答案 1 :(得分:0)

如果你可以扔掉get:

case class Foo[A](x: A)
Seq(Foo("hi"), Foo(1), Foo(2d)).collect { case f @ Foo(x: String) => f }.foreach(println)

结果:

Foo(hi)

其他人同样微不足道。