Reputation: 1157
Okay guys, I'm starting to get some scala now, but every now and then the trickier concepts get me. Let me introduce you to the fruit world:
class Fruit
class Pear extends Fruit
class Apple extends Fruit
class GrannySmith extends Apple
Now what if I want a new generic collection that allows me to pick subsets of Fruits out of the generic collection. Naive implementation:
class MyArray[T](var a:Array[T]) {
def select[U <: T] =
a.filter(_ match {
case u:U => true
case _ => false
})
}
This does not work however.
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)
The console warned about unchecked errors, rerunning with -unchecked gave this while defining MyArray:
<console>:8: warning: abstract type U in type pattern U is unchecked since it is eliminated by erasure
case u:U => true
So my understanding of type erasure is very vague. I know that it is somehow related to the limited dynamic types in the jvm, and that you can sometimes get around it using Manifests as Daniel is talking about here. What I particularly don't understand is how this works in this example, and how one could get around it.
I'm thankful for any help!
Upvotes: 2
Views: 244
Reputation: 59994
How about this? You even get the right return type.
ma.a.collect { case a: Apple => a }
Upvotes: 3