Scala - 查找具有某种类型的子类型的序列成员

时间:2012-07-02 11:34:02

标签: scala type-systems

我有以下情况:

Java lib类:

class LibClass {
  ArrayList<LibClass> children;
}

我的程序Scala代码:

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

class Lala extends MyClass
class Hoho extends MyClass

问题是:在boomMyClassInstances方法中,获取children MyClass的所有children的最常见Scala-ish方式是什么,存储在ArrayList {{1}所以我可以在它们上面调用常见的boom方法吗?

我的尝试是:

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

这是正确的做法吗?它会选择MyClass的所有子项,这是正确的Scala方式,还是我必须说一下类型边界?

4 个答案:

答案 0 :(得分:5)

import collection.JavaConverters._

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

答案 1 :(得分:4)

结帐GenTraversableLike.collect。它的签名基本上是Traversable[A].collect[B <: A](f: A ~> B): Traversable[B],也就是说,它从A到{需要一个类型为f的元素和一个部分函数A的集合{1}},并返回静态元素类型B的集合,其中BB的子类型。

A

由于val myClassInstances: List[MyClass] = children.toList.collect{case mc: MyClass => mc} 需要一个完整的功能,如果map scala.MatchError不仅包含children的实例,则上述尝试将失败并显示MyClass。您可以使用OptionflatMap解决此问题,但collect似乎是实现您想要的最多Scala-ish方式。

答案 2 :(得分:2)

我不是类型专家,所以我不能肯定地说你的解决方案会起作用,但看起来确实应该有效。它具有直截了当的优点,总是很好。

你确实需要添加一个包罗万象的案例(以便得不到scala.MatchError)。

case _ => // do nothing

答案 3 :(得分:1)

您希望collect相关部分:

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