在None子句中从Option [T]中提取类

时间:2014-08-19 09:17:44

标签: scala reflection manifest optional

假设您有以下代码

  trait T {

  }

  case class First(int:Int) extends T
  case class Second(int:Int) extends T

  val a:Option[T] = Option(First(3))

  val b:Option[Second] = None

  def test[A](a:Option[A])(implicit manifest:Manifest[Option[A]]) = {
    a match {
      case Some(z) => println("we have a value here")
      case None => a match {
        case t:Option[First] => println("instance of first class")
        case s:Option[Second] => println("instance of second class")
      }
    }
  }

  test(b)

如果选项恰好为None,您将如何提取封闭type的{​​{1}}。我试图做各种清单的组合,但它们似乎都没有用,每次它都抱怨用擦除消除的类型,即

A

1 个答案:

答案 0 :(得分:2)

您可以使用type tag,Manifest的现代替代品:

import scala.reflect.runtime.universe._

trait T
case class First(int:Int) extends T
case class Second(int:Int) extends T

def test[A: TypeTag](a: Option[A]) = {
  a match {
    case Some(_) => println("we have a value here")
    case None => typeOf[A] match {
      case t if t =:= typeOf[First] => println("instance of First")
      case t if t =:= typeOf[Second] => println("instance of Second")
      case t => println(s"unexpected type $t")
    }
  }
}

实施例

val a = Option(First(3)) // we have a value here
val b: Option[First] = None // instance of First
val c: Option[Second] = None // instance of Second
val d: Option[Int] = None // unexpected type Int

顺便说一下,你对A的类型感兴趣(通过删除消除了),所以即使有清单,你需要A而不是Option[A]