代码之家  ›  专栏  ›  技术社区  ›  Kevin Meredith

使用TypeTags检查预期类型是否与实际匹配

  •  0
  • Kevin Meredith  · 技术社区  · 10 年前

    鉴于:

    sealed trait Parent
    case class Boy(info: String) extends Parent
    case class Girl(info: String) extends Parent
    

    然后,我写了以下内容 f 作用给定 result 和预期的结果类型,它打印出检查是否成功:

    import scala.reflect.runtime.universe._
    
    scala> def f[A:TypeTag, B:TypeTag](result: A): Unit = typeOf[A] match { 
         | case t if t =:= typeOf[B] => println("good")
         | case _                    => println("bad")
         | }
    f: [A, B](result: A)(implicit evidence$1: reflect.runtime.universe.TypeTag[A], implicit evidence$2: reflect.runtime.universe.TypeTag[B])Unit
    

    然后,我运行了它:

    scala> f[Boy, Girl](Boy("foo"))
    bad
    
    scala> f[Boy, Boy](Boy("foo"))
    good
    

    出于测试目的(忽略 println 表示成功的语句),是我对 TypeTag 是正确的吗?此外,是否存在运行时异常的风险 f ? 如果是,如何?

    2 回复  |  直到 10 年前
        1
  •  4
  •   Michael Zajac    10 年前

    我对TypeTag的用法正确吗?

    TypeTag 如果您手动提供类型参数,则实际上不需要。这大致相当于:

    def f[A](result: A): Unit = ???
    

    f[Girl](boy) 如果 boy 是一个 Boy ,所以失败案例没有用处。

    对于 def f[A: TypeTag, B: TypeTag](result: A): Unit ,的实际实例 result 不需要,因为您正在手动比较 类型标记 第个,共个 A 和 B ,手动指定类型参数。这相当于说 typeOf[A] =:= typeOf[B] 没有实例。

    此外,是否存在运行时异常的风险 f ?

    不是真的。你必须做一些非常邪恶的事情,比如自己动手 类型标记 秒:

    scala> implicit val tt: TypeTag[Boy] = null.asInstanceOf[TypeTag[Boy]]
    tt: reflect.runtime.universe.TypeTag[Boy] = null
    
    scala> f[Boy, Girl](Boy("foo"))
    java.lang.NullPointerException
    

    只要使用生成的编译器 类型标记 ,应该没事。

        2
  •  0
  •   Alexey Romanov    10 年前

    以下是如何提供一个参数并推断另一个参数:

    case class F[B: TypeTag] {
      def apply[A: TypeTag](x: A) = println(typeOf[A] =:= typeOf[B])
    }
    
    F[Girl].apply(Boy("Foo")) // Boy inferred for A
    
    推荐文章