scala – 使用ClassTags / TypeTags进行模式匹配功能签名
我有一个方法,探索不同类函数的不同参数值.以前,我做了一些非类型安全的运行时检查,其中,擦除后,所有重要的是我使用的是Function2而不是Function3.我正在尝试使用ClassTags / TypeTag更安全一点,但我仍然在努力寻找一个好的解决方案.我原来的参考点是
tksfz的回答: How do I get around type erasure on Scala? Or,why can’t I get the type parameter of my collections? import reflect.ClassTag def matchList[A: ClassTag](list: List[A]) = list match { case strlist: List[String] => println("A list of strings!") case intlist: List[Int] => println("A list of ints!") case _ => println("Ok") } 但是,我发现给定的代码段不起作用,并且两种情况都匹配一个字符串列表 – 可能是答案涉及不同版本的scala(我使用的是2.10.3). 我找到了另一个例子,其中有人使用TypeTags给出了一个片段(我对类型标签类型之间的差异仍然有些模糊;我很乐意在这一点上进行RTFM响应,前提是它伴随着一个好的M到FR的链接). 编辑:我之前的例子没有应用函数,因此产生警告的匹配部分毫无意义(正如第一个回答者指出的那样).我已经更新了示例,以便更能代表我的实际问题. package misc import reflect.runtime.universe._ object CTDemo { def main(args: Array[String]) = { val f0v: Function2[Int,Double,String] = f0(_,_) val f1v: Function2[Int,(Double,Double),String] = f1(_,_) println(matchFunc(f0v)) println(matchFunc(f1v)) } def f0(i: Int,p: Double) = { s"output on $p doesn't matter" } def f1(i: Int,p: (Double,Double)) = { s"output on $p doesn't matter" } def matchFunc[I: TypeTag,A: TypeTag,O: TypeTag](predFunc: Function2[I,A,O]) = { predFunc match { case fs: Function2[Int,String] if(typeOf[A] <:< typeOf[Double]) => { "Single-arg,result is: " + fs(1,2.0) } case ds: Function2[Int,String] if(typeOf[A] <:< typeOf[(Double,Double)]) => { "Double-arg,result is: " + ds(1,(2.0,3.0)) } } } } 这种情况有效,但它仍然会抛出编译器警告.是否有一个简洁的“asInstanceOf” – 免费,无警告和线程安全的方法来检查函数的类型签名?我愿意升级到scala 2.11,如果那样会有所帮助. 解决方法
你的比赛没有做任何工作,所以只是
def matchFunc[I: TypeTag,O]) = { if (typeOf[A] <:< typeOf[Double]) { "Single-arg" } else if (typeOf[A] <:< typeOf[(Double,Double)]) { "Double-arg" } } 另一个成语就是这样做的: scala> def g[A: reflect.ClassTag](as: List[A]) = as match { case List(_: Int) => "I" } g: [A](as: List[A])(implicit evidence$1: scala.reflect.ClassTag[A])String scala> g(List(3)) res4: String = I scala> g(List(3.0)) scala.MatchError: List(3.0) (of class scala.collection.immutable.$colon$colon) at .g(<console>:7) ... 33 elided 也就是说,作为一个美化(虽然方便)isInstanceOf. 在Scala中,它是RTFS,其中S = spec或SIP. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |