generics - 从通用集合中选择类型的子集

标签 generics scala collections type-erasure

好吧,伙计们,我现在开始学习一些 scala,但时不时会遇到一些更棘手的概念。让我向您介绍水果世界:

class Fruit
class Pear extends Fruit
class Apple extends Fruit
class GrannySmith extends Apple

现在,如果我想要一个新的通用集合,该集合允许我从通用集合中挑选 Fruits 子集,该怎么办?简单的实现:

class MyArray[T](var a:Array[T]) {
  def select[U <: T] = 
    a.filter(_ match {
      case u:U => true
      case _   => false
    })
}

但这不起作用。

scala> var ma = new MyArray(
                        Array(
                          new Apple, 
                          new Fruit, 
                          new Pear, 
                          new GrannySmith, 
                          new Apple, 
                          new Fruit
                        ))


scala> ma.select[Apple]
res1: Array[Fruit] = Array(Apple@4d815146, Fruit@64fef26a, Pear@1ddd40f3, GrannySmith@28d320d6, Apple@3d10d68a, Fruit@1c751d58)

控制台警告未检查的错误,使用 -unchecked 重新运行在定义 MyArray 时给出了此信息:

<console>:8: warning: abstract type U in type pattern U is unchecked since it is eliminated by erasure
             case u:U => true

所以我对类型删除的理解非常模糊。我知道它在某种程度上与 jvm 中有限的动态类型有关,并且有时您可以使用 list 来解决它,正如 Daniel 所说的 here 。我特别不明白的是,在这个例子中它是如何工作的,以及如何绕过它。

非常感谢您的帮助!

最佳答案

这个怎么样?您甚至可以获得正确的返回类型。

ma.a.collect { case a: Apple => a }

关于generics - 从通用集合中选择类型的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7067332/

相关文章:

javascript - 通过 this 在 typescript 中从派生类型调用构造函数

c# - 使用反射查找通用列表元素的继承属性

scala - 将 Free Monad 与 Either 一起使用

java - 如何将对象从 ArrayList 的一个位置读取到另一个 ArrayList 中的同一位置

java - 在单行中排序偶数和奇数

ios - 如何创建适用于 2 个不同类的通用 swift 函数?

c# - 来自字符串值的通用类型

scala - @field注解的使用

ScalaTest 测试序列是否已排序

java - Guava:通过反转 Map 构造 Multimap