假设:
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
中是否存在运行时异常的风险?如果是这样,怎么样?
答案 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
A
和B
,您手动指定类型参数。它相当于在没有实例的情况下说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;
}
}