Type参数是未检查的,因为它由于擦除而被消除



在尝试过滤"记录"记在一个清单里。我应该得到一个列表[地图[字符串,字符串]],其中将有所有公司及其总部的位置。

non-variable type argument String in type pattern scala.collection.immutable.Map[String,String] (the underlying of Map[String,String]) is unchecked since it is eliminated by erasure
case map: Map[String, String] if map.contains("company") => new Some(Company(map.get("company").get, map.get("origin").get))

我正在学习scala,我不知道该怎么做,所以类型不会在运行时丢失

object Main {
def main(args: Array[String]): Unit = {
val data = List(
Map("name" -> "Jan", "fname" -> "Kowalski", "age" -> "45"),
Map("company" -> "ABB", "origin" -> "Sweden"),
Map("name" -> "Katarzyna", "fname" -> "Nowak", "age" -> "45"), Map("company" -> "F4", "origin" -> "Poland"),
List("Cos", "innego"),
Map("company" -> "Salina Bochnia", "origin" -> "Poland"),
Map("company" -> "AGH", "origin" -> "Poland"),
Map("name" -> "Krzysztof", "fname" -> "Krol", "age" -> "14")
)
getCompanies(data)
}

def getCompanies(toFilter: List[Any]): List[Any] ={
val result = for(record <- toFilter) yield filterRecords(record)
result.toList.filter(_ != None)
}
def filterRecords(record: Any): Option[Company] ={
record match{
case map: Map[String, String] if map.contains("company") => new Some(Company(map.get("company").get, map.get("origin").get))
case _ => None
}
}
}
case class Company (name: String, origin: String)

首先,关于什么是类型擦除,为什么会发生擦除等等,有很多资源,所以我就不在这里解释了。尝试更好的"类型",在您的场景中,您的数据由List[String]Map[String, String]组成,在Scala3中,您可以使用联合类型轻松处理它,但更好的解决方案是对输入数据施加限制,并尝试将它们包装成您在编译时知道的东西。这样的:

trait ListElement // can also be sealed, depends on what you have
case class ListHolder(value: List[String]) extends ListElement
case class MapHolder(value: Map[String, String]) extends ListElement

我还会为trait创建一个伴侣对象,以便更容易创建对象:

object ListElement {
def apply(arg: List[String]): ListElement = ListHolder(arg)
def apply(arg: Map[String, String]): ListElement = MapHolder(arg)
}

现在让我们重新创建您的数据:

val data: List[ListElement] = List(
ListElement(Map("name" -> "Jan", "fname" -> "Kowalski", "age" -> "45")),
ListElement(List("Cos", "innego")),
// ... other data here
)

现在我将重写你的函数如下,有更好的输入,更容易跟踪和更安全:

def filterRecord(record: ListElement): Option[Company] = record match {
case MapHolder(myMap) => myMap.get("company").map { companyName => 
Company(
companyName,
myMap.get("origin").get // PLEASE do not use .get, .getOrElse would be safer
)
}
case _ => None
}
def getCompanies(toFilter: List[ListElement]): List[Company] = 
toFilter.map(filterRecord).collect {
case Some(company) => company
}

最新更新