Scala按类型收集过滤器 [英] Scala collection filter by type

查看:162
本文介绍了Scala按类型收集过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我想获取只包含特定类型元素的现有集合的子集合。下面的工作:

pre code $ class C(val name:String)
class D(name:String)extends C新的C(C1),新的D(D1),新的C(C2),新的D(D2 ))
collection.collect {case d:D => d} .size必须是=== 2 //工程

但是当我尝试扩展集合带有方法onlyInstancesOf [Type]的类不起作用。首先我的实现:

pre code $ object隐藏def extendScalaCollection [E](coll:Traversable [E])= new CollectionExtension [E](coll)
}

class CollectionExtension [E](coll:Traversable [E]){

def onlyInstancesOf [SpecialE< ;: E:Traversable [SpecialE] = {
coll.collect({case special:SpecialE => special})。asInstanceOf [Traversable [SpecialE]]
}
}

所以当我使用这个扩展名并执行时:

  collection.onlyInstancesOf [D] .size必须是=== 2 

我得到一个错误,.size返回4而不是2.另外,我检查,结果实际上包含C1和C2,虽然它不应该。



当我这样做:

  collection.onlyInstancesOf [D] .foreach(e => println(e.name))
code>

我得到这个例外:

  java.lang.ClassCastException:Collec tionsSpec $$ anonfun $ 1 $ C $ 1不能转换为CollectionsSpec $$ anonfun $ 1 $ D $ 1 

显然结果集仍然包含应该被过滤掉的元素。

我不明白为什么发生这种情况,任何人都可以解释这一点吗?

编辑:
Scala:Scala代码运行器版本2.8.0.final

解决方案

注意编译器警告,并添加-unchecked你的scala命令行选项。

  M:\> scala -unchecked 
欢迎使用Scala 2.8.0.final(Java HotSpot(TM)客户机VM,Java 1.6.0_21)

键入表达式让他们评估。
输入:help获取更多信息。

scala> class CollectionExtension [E](coll:Traversable [E]){
|
| def onlyInstancesOf [SpecialE<:E]:Traversable [SpecialE] = {
| coll.collect({case special:SpecialE => special})。asInstanceOf [Traversable [SpecialE]]
| }
| }
< console>:8:warning:抽象类型SpecialE在类型模式下SpecialE被取消选中,因为它被擦除
coll.collect({case special:SpecialE => special})。asInstanceOf [Traversable [SpecialE]]
^
定义的类CollectionExtension

编译器可以做的最好的是相当于:

$ p code> coll.collect({case special:AnyRef => special}) .asInstanceOf [Traversable [_]]

有关类型擦除的更详细的解释,在Manifests附近解决它,请参阅:

https:/ /stackoverflow.com/questions/tagged/type-erasure+scala


im new to scala and ran into the following problem:

I want to get a subcollection of an existing collection that only contains elements of a specific type. The following works:

class C(val name : String)
class D(name : String) extends C(name) { }

val collection = Set[C](new C("C1"),new D("D1"),new C("C2"),new D("D2"))
collection.collect{case d : D => d}.size must be === 2 // works

But when i try to extend the collection classes with a method "onlyInstancesOf[Type]" this does not work. First my implementation:

object Collection {
    implicit def extendScalaCollection[E](coll : Traversable[E]) = new CollectionExtension[E](coll)
}

class CollectionExtension[E](coll : Traversable[E]) {

    def onlyInstancesOf[SpecialE <: E] : Traversable[SpecialE] = {
        coll.collect({case special : SpecialE => special}).asInstanceOf[Traversable[SpecialE]]
    }
}

So when i use this extension and execute:

collection.onlyInstancesOf[D].size must be === 2

I get an error that .size returned 4 and not 2. Also, i checked, the result actually contains C1 and C2 though it should not.

When i do:

collection.onlyInstancesOf[D].foreach(e => println(e.name))

I get the exception:

java.lang.ClassCastException: CollectionsSpec$$anonfun$1$C$1 cannot be cast to CollectionsSpec$$anonfun$1$D$1

So obviously the resulting set still contains the elements that should have been filtered out.

I dont get why this happens, can anyone explain this?

Edit: Scala: Scala code runner version 2.8.0.final

解决方案

Pay attention to the compiler warnings, and add -unchecked your scala command line options.

M:\>scala -unchecked
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Client VM, Java 1.6.0_21)
.
Type in expressions to have them evaluated.
Type :help for more information.

scala> class CollectionExtension[E](coll : Traversable[E]) {
     |
     |     def onlyInstancesOf[SpecialE <: E] : Traversable[SpecialE] = {
     |         coll.collect({case special : SpecialE => special}).asInstanceOf[Traversable[SpecialE]]
     |     }
     | }
<console>:8: warning: abstract type SpecialE in type pattern SpecialE is unchecked since it is eliminated by erasure
               coll.collect({case special : SpecialE => special}).asInstanceOf[Traversable[SpecialE]]
                                            ^
defined class CollectionExtension

The warning means that the best the compiler can do is equivalent to:

coll.collect({case special : AnyRef => special}).asInstanceOf[Traversable[_]]

For a more detailed explanation of type erasure, and ways you can work around it with Manifests, see:

https://stackoverflow.com/questions/tagged/type-erasure+scala

这篇关于Scala按类型收集过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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