[英]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几个可能的重写值得记住
filter
followed by map
as collect
filter
后跟map
作为collect
isInstanceOf
followed by asInstanceOf
as pattern match with typed pattern isInstanceOf
后跟asInstanceOf
作为与类型化模式匹配的模式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.