Scala 用于理解和部分映射
Scala 语言规范部分 6.19 说:
A 的理解
for (p <- e) yield e0
被翻译为e.map { case p =>; e0 }
那么...
scala> val l : List[Either[String, Int]] = List(Left("Bad"), Right(1))
l: List[Either[String,Int]] = List(Left(Bad), Right(1))
scala> for (Left(x) <- l) yield x
res5: List[String] = List(Bad)
到目前为止一切顺利:
scala> l.map { case Left(x) => x }
<console>:13: warning: match is not exhaustive!
missing combination Right
l.map { case Left(x) => x }
^
scala.MatchError: Right(1)
at $anonfun$1.apply(<console>:13)
at ...
为什么第二个版本不起作用?或者更确切地说,为什么第一个版本有效?
The Scala language specification section 6.19 says:
A for comprehension
for (p <- e) yield e0
is translated toe.map { case p => e0 }
So...
scala> val l : List[Either[String, Int]] = List(Left("Bad"), Right(1))
l: List[Either[String,Int]] = List(Left(Bad), Right(1))
scala> for (Left(x) <- l) yield x
res5: List[String] = List(Bad)
So far so good:
scala> l.map { case Left(x) => x }
<console>:13: warning: match is not exhaustive!
missing combination Right
l.map { case Left(x) => x }
^
scala.MatchError: Right(1)
at $anonfun$1.apply(<console>:13)
at ...
Why does the second version not work? Or rather, why does the first version work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您在
for
理解中使用模式匹配,编译器实际上会在应用之前插入对
。filter
的调用,并使用instanceOf
检查>地图编辑:
第 6.19 节中还提到:
生成器之前定义为:
检查字节码时,您将看到对
filter
的调用位于对map
的调用之前。If you use pattern matching in your
for
-comprehension the compiler will actually insert a call tofilter
with aninstanceOf
-check before applying themap
.EDIT:
Also in section 6.19 it says:
A generator is defined earlier on as:
When inspecting the bytecode you will see the call to
filter
preceding the call tomap
.作为Eastsun评论的补充:Scala 2.8有一个方法collect,它可以在你的示例中工作:
As an addition to Eastsun's remarks: Scala 2.8 has a method collect, which would work in your example:
Scala 2.7 语言规范,第 83 页,倒数第二段(此处没有 2.8 规范)。插入用于生成器模式匹配的过滤器是理解翻译过程的第一步。
需要注意的是,我上次检查时,这不适用于键入的模式,这可能会令人惊讶。所以在你的例子中
是行不通的,会抛出类型错误
Scala 2.7 language specification, page 83, second paragraph from the bottom (don't have the 2.8 spec here). Inserting filters for generator pattern-matching is the first step in the for-comprehension translation process.
One caveat, the last time I checked, this doesn't work for typed patterns, which can be surprising. So in your example
wouldn't work, throwing a type error