scala 中的擦除消除:未选中非变量类型参数,因为它已被擦除消除 [英] Erasure elimination in scala : non-variable type argument is unchecked since it is eliminated by erasure

查看:43
本文介绍了scala 中的擦除消除:未选中非变量类型参数,因为它已被擦除消除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个序列 Seq[Any],其中包含各种对象(如 String、Integer、List[String] 等).我正在尝试筛选列表并将其分解为基于类类型分区的单独列表.以下是我在代码中使用的模式:

I've got a sequence Seq[Any] that has a variety of objects in it (like String, Integer, List[String], etc). I'm trying to sift through the list and break it up into separate lists partitioned based on the class type. The following is a pattern I'm using in the code:

val allApis = mySequence.filter(_.isInstanceOf[String])

这很有效,并且不会产生任何警告.但是,当我尝试做同样的事情来过滤掉字符串列表的对象时:

This works well and doesn't generate any warnings. However, when I try to do the same for filtering out the objects that are Lists of strings:

val allApis = mySequence.filter(_.isInstanceOf[List[String]])

我收到一条警告,指出类型 List[String] 中的非变量类型参数 String 未选中,因为它已被擦除.现在,该技术确实有效,我可以根据需要轻松地过滤序列,但我想知道以惯用方式处理警告的适当方法是什么,以便我知道我没有严重的错误潜伏在后台等待爆炸

I get a warning that says non-variable type argument String in type List[String] is unchecked since it is eliminated by erasure. Now, the technique actually works and I'm able to comfortably filter the sequence as desired, but I'm wondering what is the appropriate way to deal with the warning in an idiomatic way so that I know I don't have a serious bug lurking in the background waiting to blow up

推荐答案

它不起作用,因为它会选择 List[Double] 或除 List[ 之外的任何其他列表字符串].有多种解决问题的方法,包括将任何参数化类型包装在非参数化案例类中:

It doesn't work because it will pick out List[Double] or any other list in addition to List[String]. There are a variety of ways of fixing the problem, including wrapping any parameterized types in a non-parameterized case class:

case class StringList(value: List[String])

然后你就可以了

mySequence.collect{ case StringList(xs) => xs }

提取字符串列表(具有正确的类型,并且类型安全).

to pull out the lists of strings (with the correct type, and type-safely also).

或者,如果您不想包装对象并希望确保它们的类型正确,您可以检查每个元素:

Alternatively, if you want to not wrap objects and want to be sure that they're of the correct type, you can check every element:

mySequence.filter( _ match {
  case xs: List[_] => xs.forall( _ match { case _: String => true; case _ => false })
  case _ => false
})

即使这样也不能让您知道空列表应该是哪种类型.

though even this won't let you know which type empty lists were supposed to be.

另一种可能性是将 TypeTag 粘贴到列表中的所有内容;这将防止您需要手动包装东西.例如:

Another possibility is to glue TypeTags to everything in your list; this will prevent you needing to manually wrap things. For instance:

import scala.reflect.runtime.universe.{TypeTag, typeTag}
def add[A](xs: List[(Any, TypeTag[_])], a: A)(implicit tt: TypeTag[A]) = (a, tt) :: xs
val mySequence = add(add(add(Nil, List(42)), true), List("fish"))
mySequence.filter(_._2.tpe weak_<:< typeTag[List[String]].tpe)

这篇关于scala 中的擦除消除:未选中非变量类型参数,因为它已被擦除消除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆