Scala---For语句段
為什么80%的碼農都做不了架構師?>>> ??
For語句段
語法:
Expr1 ::= ?for? (?(? Enumerators ?)? | ?{? Enumerators
?}?) {nl} [?yield?] Expr
Enumerators ::= Generator {semi Enumerator}
Enumerator ::= Generator
| Guard
| ?val? Pattern1 ?=? Expr
Generator ::= Pattern1 ?<-? Expr [Guard]
Guard ::= ?if? PostfixExpr
for語句段for (enums) yield e對于由枚舉器enums產生的每個綁定求值表達式e。一個枚舉器序列總是由一個產生器開始;然后可跟其他產生器,值定義,或守衛(wèi)。一個產生器 p <- e從一個與模式p匹配的表達式e產生綁定。值定義val p = e將值名稱p(或模式p中的數(shù)個名稱)綁定到表達式e的求值結果上。守衛(wèi)if e包含一個布爾表達式,限制了枚舉出來的綁定。產生器和守衛(wèi)的精確含義通過翻譯為四個方法的調用來定義:map filter flatMap和foreach。這些方法可以針對不同的攜帶類型具有不同的實現(xiàn)。
翻譯框架如下。在第一步里,每個產生器p <- e,對于e的類型被替換為如下形式,p不是不可反駁的(§8.1):
p <- e.filter { case p => true; case _ => false }
然后,以下規(guī)則將重復應用,直到所有的語句段都消耗完畢。
? for語句段 for (p <- e) yield e?被翻譯為e.map { case p => e? }
? for語句段 for (p <- e) e? 被翻譯為e.foreach { case p => e? }
? for語句段 for (p <- e; p? <- e? ...) yield e??, 這里...是一個產生器或守衛(wèi)序列(可能為空),該語句段翻譯為 e.flatMap { case p => for(p? <- e? ...) yield e?? }
? for語句段 for (p <- e; p? <- e? ...) e??
這里... 是一個產生器或守衛(wèi)序列(可能為空),該語句段翻譯為 e.foreach { case p => for (p? <- e? ...) e?? }
? 后跟守衛(wèi)if g的產生器p <- e翻譯為單個產生器p <- e.filter((x1,...,xn) => g),這里x1,...,xn是p的自由變量。
? 后跟值定義val p? = e?的產生器 p <- e翻譯為以下值對產生器,這里的x和x?是新名稱: val (p, p?) <- for (x@p <- e) yield { val x?@p? = e?; (x, x?) }
示例6.19.1 以下代碼產生1到n-1間所有和為素數(shù)的數(shù)值對
for { i <- 1 until n
j <- 1 until i
if isPrime(i+j)
} yield (i, j)
該for語句段翻譯為:
(1 until n)
.flatMap {
case i => (1 until i)
.filter { j => isPrime(i+j) }
.map { case j => (i, j) }
示例6.19.2 for語句段可以用來簡明地描述向量和矩陣算法。比如以下就是一個函數(shù)來計算給定矩陣的轉置:
def transpose[A](xss: Array[Array[A]]) = {
for (i <- Array.range(0, xss(0).length)) yield
for (xs <- xss) yield xs(i)
}
以下是一個函數(shù),用來計算兩個向量的無向量積:
def scalprod(xs: Array[Double], ys: Array[Double]) = {
var acc = 0.0
for ((x, y) <- xs zip ys) acc = acc + x * y
acc
}
最后,這是一個求兩個矩陣的積的函數(shù)。可以與示例 6.15.1中的常見版本做一個比較
def matmul(xss: Array[Array[Double]], yss: Array[Array[Double]] = {
val ysst = transpose(yss)
for (xs <- xss) yield
for (yst <- ysst) yield
scalprod(xs, yst)
}
以上代碼使用了類scala.Array中已有定義的成員map, flatMap, filter和foreach。
更多精彩內容請關注:http://bbs.superwu.cn
關注超人學院微信二維碼:
關注超人學院java免費學習交流群:
轉載于:https://my.oschina.net/crxy/blog/424359
總結
以上是生活随笔為你收集整理的Scala---For语句段的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java http方式提交短信到短信网关
- 下一篇: bzoj 2435: [Noi2011]