简体   繁体   English

提取 Scala 中的后代子列表

[英]Extract sublist of descendants in Scala

I have a class Foo extends Bar and a List or other collection of base class:我有一个class Foo extends Bar和一个List或其他基本 class 集合:

val bars: Iterable[Bar] 

I need to extract all Foo elements from the collection.我需要从集合中提取所有Foo元素。 The following is the code:以下是代码:

val fooes: Iterable[Foo] = bars
    .filter(x => Try(x.isInstanceOf[Foo]).isSuccess))
    .map(_.isInstanceOf[Foo])

Is there conciser approach?有更简洁的方法吗?

val fooes: Iterable[Foo] = bars.collect{case foo:Foo => foo}

The .collect() method takes a partial-function as its parameter. .collect()方法将偏函数作为其参数。 In this case the function is defined only for Foo types.在这种情况下,function 仅为Foo类型定义。 All others are ignored.所有其他都被忽略。

Couple of possible rewrites worth remembering in general几个可能的重写值得记住

Hence the following discouraged style因此以下不鼓励的风格

bars
  .filter { _.isInstanceOf[Foo] }
  .map    { _.asInstanceOf[Foo] }

can be rewritten to idiomatic style可以改写成惯用风格

bars collect { case foo: Foo => foo }

...writing type tests and casts is rather verbose in Scala. ...在 Scala 中编写类型测试和强制转换相当冗长。 That's intentional, because it is not encouraged practice.这是故意的,因为它不被鼓励练习。 You are usually better off using a pattern match with a typed pattern.通常最好使用带有类型化模式的模式匹配。 That's particularly true if you need to do both a type test and a type cast, because both operations are then rolled into a single pattern match.如果您需要同时进行类型测试和类型转换,则尤其如此,因为这两个操作随后都会被滚动到单个模式匹配中。

Note the nature of typed pattern is still just runtime type check followed by runtime type cast , that is, it merely represent nicer stylistic clothing not an increase in type safety.请注意,类型化模式的本质仍然只是运行时类型检查,然后是运行时类型转换,也就是说,它仅代表更好的风格服装,而不是类型安全性的增加。 For example例如

scala -print -e 'lazy val result: String = (42: Any) match { case v: String => v }'

expands to something like扩展到类似的东西

<synthetic> val x1: Object = scala.Int.box(42);
if (x1.$isInstanceOf[String]()) {
  <synthetic> val x2: String = (x1.$asInstanceOf[String]());
  ...
}

where we clearly see type check isInstanceOf followed by type cast asInstanceOf .我们清楚地看到类型检查isInstanceOf后跟类型asInstanceOf

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM