문제

I have the following situation:

Java lib class:

class LibClass {
  ArrayList<LibClass> children;
}

my program Scala code:

abstract class MyClass extends LibClass {
  def boom { }
  def boomMyClassInstances  // ???
}

class Lala extends MyClass
class Hoho extends MyClass

The question is: in the method boomMyClassInstances what is the most Scala-ish way to get all the children of MyClass, stored in the children ArrayList so that I can call the common boom method upon them all?

My try is:

def boomMyClassInstances {
  children.toArray.map { case mc: MyClass => mc.boom }
}

Is this a correct approach? Will it pick all the children of MyClass and this is the right Scala way for that, or do I have to say something about type bounds?

도움이 되었습니까?

해결책

Check out GenTraversableLike.collect. Its signature essentially is Traversable[A].collect[B <: A](f: A ~> B): Traversable[B], that is, it takes a collection with elements of type A and a partial function f from A to B, and returns a collection of static element-type B, where B is a subtype of A.

val myClassInstances: List[MyClass] =
  children.toList.collect{case mc: MyClass => mc}

Since map expects a total function, your try above will fail with an scala.MatchError in case children does not only contain instances of MyClass. You can work around this by using Option or flatMap, but collect seems to be the most Scala-ish way of achieving what you want.

다른 팁

import collection.JavaConverters._

children.asScala.foreach { 
  case mc: MyClass => mc.boom 
  case _ => ()
}

I'm not a type expert, so I can't say definitively that your solution will work, however it does seem that it should work. It has the advantage of being straightforward, which is always good.

You do need to add a catch-all case though (so as to not get a scala.MatchError).

case _ => // do nothing

You want to collect the relevant portion:

children.iterator collect { case mc: MyClass => mc } foreach (_.boom())
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top