模式匹配中的Scala类型擦除Map [String,Int]
发布时间:2020-12-16 18:51:21 所属栏目:安全 来源:网络整理
导读:在 Scala 2.10中,编译器会警告给定的代码: private def getStrFromOpt[T](opt: Option[T]): String = opt match { case Some(s: String) = s case Some(i: Int) = i.toString() case Some(l: Long) = l.toString() case Some(m: Map[String,Int]) = m map (
在
Scala 2.10中,编译器会警告给定的代码:
private def getStrFromOpt[T](opt: Option[T]): String = opt match { case Some(s: String) => s case Some(i: Int) => i.toString() case Some(l: Long) => l.toString() case Some(m: Map[String,Int]) => m map ({ case (k,v) => "(" + k + "," + v + ")" }) mkString ("(",",")") case _ => "" } 使用消息非变量类型参数类型模式中的字符串Map [String,Int]未被选中,因为它被擦除消除:case Some(m:Map [String,Int])…. 我怎么能摆脱这个警告?如果我想在此匹配中包含Map [String,MyObj]作为案例,该怎么办?如何通过参数化地图区分这两种情况? 解决方法
您可以使用Scala注释@unchecked来抑制警告,
对于你的第二个问题,我建议你使用Scala反射 – TypeTag.我使用的是Scala 2.11.4,这里是示例代码,FYI. import scala.reflect.runtime.{ universe => ru } import scala.reflect.runtime.universe.{ typeTag,TypeTag } object MapType extends App { def getTypeTag[T: TypeTag](t: T) = typeTag[T].tpe def getTypeTag[T: TypeTag] = ru.typeOf[T] // context bound T: ru.TypeTag cause typeOf // requires implicit parameter def getStrFromOpt[T: TypeTag](opt: Option[T]): String = { opt match { case Some(s: String) => s case Some(i: Int) => i.toString() case Some(l: Long) => l.toString() case Some(m: Map[String,Int] @ unchecked) if getTypeTag[T] =:= getTypeTag[Map[String,Int]] => "Int Map" case Some(m: Map[String,String] @ unchecked) if getTypeTag[T] =:= getTypeTag[Map[String,String]] => "String Map" case _ => "" } } // "Int Map" println(getStrFromOpt(Some(Map("a" -> 2,"b" -> 3)))) // "String Map" println(getStrFromOpt(Some(Map("a" -> "2","b" -> "3")))) } 实际上,Scala就像Java那样使用泛型的擦除模型.因此,在运行时不会保留有关类型参数的信息. def isIntMap(x: Any) = x match { case m: Map[Int,Int] => true case _ => false } 对于上面的代码,Scala编译器无法确定m是否是Map [Int,Int].因此,isIntMap(Map(“a” – >“b”))返回true,这似乎是非直观的. 但是,Array是一个Exception,它的元素类型与元素值一起存储. def isIntArray(x: Any) = x match { case a: Array[String] => "yes" case _ => "no" } scala> isIntArray(Array(3)) res1: String = no scala> isIntArray(Array("1")) res2: String = yes (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容