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