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

时间:2015-12-29 17:09:18

标签: scala

假设:

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 个答案:

答案 0 :(得分:4)

  

我对TypeTag的使用是否正确?

如果您手动提供类型参数,则不需要

TypeTag。这大致相当于:

def f[A](result: A): Unit = ???
如果f[Girl](boy)boy,则

Boy甚至无法编译,因此失败案例不会有用。

对于def f[A: TypeTag, B: TypeTag](result: A): Unit,我不需要result的实际实例,因为您需要手动比较TypeTag AB ,您手动指定类型参数。它相当于在没有实例的情况下说typeOf[A] =:= typeOf[B]

  

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

不是真的。你必须做一些非常邪恶的事情,比如制作你自己的TypeTag

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

只要您使用编译器生成的TypeTag,就应该没问题。

答案 1 :(得分:0)

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

private static DataTable getReadingTableFromSchema()
{
    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalDbConnnectionString"].ConnectionString))
    {
        string sql = "SELECT * FROM [Readings]";
        conn.Open();
        SqlCommand cmd = new SqlCommand(sql, conn);
        SqlDataReader reader = cmd.ExecuteReader();
        DataTable dtbl = reader.GetSchemaTable();
        return dtbl;
    }
}