当前位置: 首页 > 知识库问答 >
问题:

Scala中的“未检查类型模式”警告?

严宸
2023-03-14

假设我有一个mapm: Map[Any, Int]。现在我只想从m中获取条目(String, Int)并创建一个新的mapm1: Map[String, Int]与这些条目。

我正在尝试做以下事情:

val m1: Map[String, Int] = m collect {case e:(String, Int) => e}

这似乎可行,但我得到了一个警告:类型模式(String,Int)中的非变量类型参数字符串未选中,因为它已被擦除消除。

我怎样才能摆脱警告?

共有3个答案

宓文斌
2023-03-14

仔细的测试将表明您的解决方案实际上与映射中的所有内容都匹配,而不仅仅是类型(String, Int)的条目。编译器的警告告诉您,匹配的类型将在运行时被丢弃,因此您的代码实际上正在执行这样的操作:

val m1: Map[String, Int]=m收集{case e: Tuple2[任何,任何]=

并且asInstanceOf调用不会爆炸,因为它只转换为Tuple2并且(String, Int)位由于擦除而再次丢失。不过,当您尝试针对结果进行迭代时,您会遇到严重的失败......

在 REPL 中尝试此操作

  val m:Map[String,Int] = Map("2" -> 3, 3 -> 4, "6" -> 10) collect {case e:(String, Int) => e}
  // Oops, thought we would get '2'
  m size 
  // Nothing wrong with this code except m contains some
  // hidden nasties which causes us to blow up
  for ((s:String, i:Int) <- m) yield s.length + i 

`

冷善
2023-03-14

(仅供参考。你要的是virtualeyes的答案。)

val m1: Map[String, Int] = m flatMap { e =>
  e._1 match {
    case e1: String => Some(e1 -> e._2)
    case _ => None
  }
}
羊和光
2023-03-14

您可能想要:

val m1: Map[String, Int] = m collect {case (k:String, v:Int) => k->v}
 类似资料:
  • 我大致了解什么是类型擦除以及为什么我们会遇到未经检查的警告。但是,我不明白为什么在以下情况下只发出一个未经检查的警告: 不幸的是,两个接听电话都与大小写子句匹配。编译器确实为第一个子句发出了警告: 警告:未检查类型模式列表[Double]中的非可变类型参数Double,因为它已被擦除消除。 我知道TypeTag[T]可以用来实现更好的类型安全。但是我在这里关心的是为什么没有针对第二个case子句发

  • 定义以下结构: 和下面的函数(请注意,第二行是类型检查错误点,它也是一个短路结果的算法错误,但它还是出现了,我想知道为什么类型检查没有发现它) 我知道scala也有类型擦除的问题,但我很惊讶在这种情况下,在编译时却检测不到这一点?在本例中是,而显然属于类型? 听起来这里有一个很长的解释https://gist.github.com/jkpl/5279EE05CCA8CC1EC452FC26ACE5

  • 有四种不同的类型:地点、语言、技术和行业。每个类型都有一个存储库,可以返回这些类型的集合。例如位置列表。每个类型都有一个类型为String的name属性。有一个字符串列表。它可以包含位置、语言等名称。我想编写一个函数来查找那些与字符串列表名称匹配的类型实体(位置、语言、...)。我在想这样的事情: 这是不正确的,那么如何对集合进行查询,然后如何确定name属性是否存在呢?

  • JLS 5.1.9将未检查的转换定义如下: 让G用n个类型参数命名一个泛型类型声明。 从原始类或接口类型G到形式

  • 我有一个从提取的代码,对于多个子类来说,这个代码看起来应该完全相同,所以我尽量避免重复。但是,实际上(见下文),scala认为是一个泛型的,返回的值类型为,当然,它没有和方法。 问题是在这里避免重复的适当方法是什么?我对将转换为字符串并不那么着迷,因为这段代码可以使用刚从字符串解析为AST的json。我开始考虑为我需要的三种类型编写包装器,并将这些类型的匹配和隐式转换器转换为包装器,然后为这些包装