在 Scala 中提取后代的子列表
Extract sublist of descendants in Scala
我有一个 class Foo extends Bar
和一个 List
或其他基础集合 class:
val bars: Iterable[Bar]
我需要从集合中提取所有 Foo
元素。以下是代码:
val fooes: Iterable[Foo] = bars
.filter(x => Try(x.isInstanceOf[Foo]).isSuccess))
.map(_.isInstanceOf[Foo])
有没有更简洁的方法?
val fooes: Iterable[Foo] = bars.collect{case foo:Foo => foo}
.collect()
方法将部分函数作为其参数。在这种情况下,该函数仅为 Foo
类型定义。所有其他的都被忽略。
总的来说值得记住的几个可能的重写
filter
后跟 map
作为 collect
isInstanceOf
后跟 asInstanceOf
作为与 typed pattern 的模式匹配
因此出现以下 discouraged 样式
bars
.filter { _.isInstanceOf[Foo] }
.map { _.asInstanceOf[Foo] }
可以重写为惯用风格
bars collect { case foo: Foo => foo }
...writing type tests and casts is rather verbose in 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.
请注意,打字图案的本质仍然只是 runtime type check followed by runtime type cast,也就是说,它仅代表更好的风格服装,而不是增加打字安全性。例如
scala -print -e 'lazy val result: String = (42: Any) match { case v: String => v }'
扩展为
<synthetic> val x1: Object = scala.Int.box(42);
if (x1.$isInstanceOf[String]()) {
<synthetic> val x2: String = (x1.$asInstanceOf[String]());
...
}
我们清楚地看到类型检查 isInstanceOf
之后是类型转换 asInstanceOf
.
我有一个 class Foo extends Bar
和一个 List
或其他基础集合 class:
val bars: Iterable[Bar]
我需要从集合中提取所有 Foo
元素。以下是代码:
val fooes: Iterable[Foo] = bars
.filter(x => Try(x.isInstanceOf[Foo]).isSuccess))
.map(_.isInstanceOf[Foo])
有没有更简洁的方法?
val fooes: Iterable[Foo] = bars.collect{case foo:Foo => foo}
.collect()
方法将部分函数作为其参数。在这种情况下,该函数仅为 Foo
类型定义。所有其他的都被忽略。
总的来说值得记住的几个可能的重写
filter
后跟map
作为collect
isInstanceOf
后跟asInstanceOf
作为与 typed pattern 的模式匹配
因此出现以下 discouraged 样式
bars
.filter { _.isInstanceOf[Foo] }
.map { _.asInstanceOf[Foo] }
可以重写为惯用风格
bars collect { case foo: Foo => foo }
...writing type tests and casts is rather verbose in 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.
请注意,打字图案的本质仍然只是 runtime type check followed by runtime type cast,也就是说,它仅代表更好的风格服装,而不是增加打字安全性。例如
scala -print -e 'lazy val result: String = (42: Any) match { case v: String => v }'
扩展为
<synthetic> val x1: Object = scala.Int.box(42);
if (x1.$isInstanceOf[String]()) {
<synthetic> val x2: String = (x1.$asInstanceOf[String]());
...
}
我们清楚地看到类型检查 isInstanceOf
之后是类型转换 asInstanceOf
.