在Scala中,从for循环块中返回一个值。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Scala中,从for循环块中返回一个值。相关的知识,希望对你有一定的参考价值。
在 "Scala for the impatient "一书中,第16页写道
在Scala中,一个{ }块包含一个表达式序列,结果也是一个表达式。块的值就是最后一个表达式的值。
OK,那么我们创建一个块,让块的最后一个值被赋值。
scala> val evens = for (elem <- 1 to 10 if elem%2==0) {
| elem
| }
val evens: Unit = ()
我本以为 evens
至少是序列的最后一个值(即 10
). 但为什么不这样做呢?
Unit
是你书中所说的规则的例外。Unit
基本上说,"不管块会返回什么类型,都要忽略,因为我只打算执行块的副作用"。否则,为了让它进行类型检查,你必须在任何一个本应返回的块的末尾添加一个单位值。Unit
:
val evens = for (elem <- 1 to 10 if elem%2==0) {
elem
()
}
这种类型信息的浪费是人们倾向于避免在Scala中使用imperative for循环和类似的方法的原因之一。
你需要 yield
的值,那么它就是一个for表达式。
val evens = for (elem <- 1 to 10 if elem % 2 == 0) yield elem
如果没有这一点,它只是一个语句(不返回任何东西),并被翻译为 foreach
.
P.S.: 当然,这将返回所有满足谓词的元素的集合,而不是最后一个。
当有疑问时,只需通过tyechecker来运行它,就可以窥探到它的本质。
scala -Xprint:typer -e 'val evens = for (elem <- 1 to 10 if elem%2==0) { elem }'
揭示
val evens: Unit =
scala.Predef
.intWrapper(1)
.to(10)
.withFilter(((elem: Int) => elem.%(2).==(0)))
.foreach[Int](((elem: Int) => elem))
我们看到 foreach
是该链的最后一步,其签名是
def foreach[U](f: A => U): Unit
在那里我们看到它返回 Unit
. 您甚至可以直接在 REPL 中执行以下命令来完成这项工作
scala> :settings -Xprint:typer
而现在,你将在解释Scala表达式的同时获得实时的去ugaring。你甚至还可以更进一步,在JVM字节码中获取
scala> :javap -
For-comprehensions是Scala中最盛行的一些语法糖,所以我建议尽可能地操练它们,或许试着同时写它们的suggared和desugared from,直到它点击为止。https:/docs.scala-lang.orgtutorialsFAQyield.html
以上是关于在Scala中,从for循环块中返回一个值。的主要内容,如果未能解决你的问题,请参考以下文章