9. for式
for(ジェネレータ1; ジェネレータ2; ... ジェネレータn) A
for(a1 <- exp1; a2 <- exp2; ... an <- expn) A
一般例
具体例
変数a1〜an:ループ変数
exp1~expn:式。例えば、ある数の範囲を表す式
※「1 to 10」や「1 until 10」
10. for式の具体例
for(x <- 1 to 3; y <- 1 until 4 if x != y){
println("x = " + x + " y = " + y)
}
x = 1 y = 2
x = 1 y = 3
x = 2 y = 1
x = 2 y = 3
x = 3 y = 1
x = 3 y = 2
各変数に対する計算式
出力結果
11. for式の具体例2
val fileHere = (new java.io.file(“.”)).listfiles
for( file <- filesHere )
println(file)
良い例
val fileHere = (new java.io.file(“.”)).listfiles
for( i <- 0 to fileHere.length - 1 )
println(filesHere(i))
駄目な例
Scalaではコレクションを直接反復処理できる。
その方がコードは短くなるし、
数値の境界値におけるエラー等を避けられる。
例:「0 to 9」 を 「1 to 10」にしてしまう等のエ
ラーを直接コレクションを弄る事により無くせる。
12. for式のフィルタリング
val fileHere = (new java.io.file(“.”)).listfiles
for(
file <- filesHere
if file.isFile // ファイルであるか?
if file.getName.endswith(“.scala”) // 末尾が”.scala”であるか?
)
println(file)
フィルタリング
if文を複数追加可能
13. for式の入れ子の反復処理
for(i <- 0 to 4 if i % 2 == 0;x <- 0 to 4 if x % 2 != 0){
println("i = " + i + "; x = " + x)
}
i = 0; x = 1
i = 0; x = 3
i = 2; x = 1
i = 2; x = 3
i = 4; x = 1
i = 4; x = 3
複数のコレクションi = 0に対して
x = 0 ~ 4
i = 2に対して
x = 0 ~ 4
...
14. 変数への中間結果の束縛
for{
line <- fileLines(file)
if line.trim.matches(pattern)
} println(file + “: ” + line.trim)
for{
line <- fileLines(file)
trimed = line.trim
if trimed.matches(pattern)
} println(file + “: ” + trimmed)
line.trimが複数回呼ばれるので、
等号(=)を使って変数に結果を束
縛する。束縛というのは、等号の
左辺と右辺の式の結果値を紐付け
る。要は、この式の中だけで有効
な代入である。
15. 新しいコレクションの作成
scala> var a = for{i <- 0 to 6 if i % 2 == 0} yield i
a: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4,
6)
今までの例では、反復的に生成された値をその場で使用した
だけでしたが、yieldを使い、値を保存する事ができます。
for {節} yield <本体>
一般例
具体例
生成された値
を格納していく
16. ifとforを使った練習問題
1から100までの3つの整数a, b, cについて、三辺からなる三
角形が直角三角形になるような a, b, cの組み合わせを全て出
力してください。直角三角形の条件にはピタゴラスの定理を
利用してください。 ピタゴラスの定理とは三平方の定理とも
呼ばれ、a ^ 2 == b ^ 2 + c ^ 2を満たす、a, b, c の長さの三辺
を持つ三角形は、直角三角形になるというものです。
要は、a^2 == b^2 + c^2
となるa,b,cの組み合わせを出力してください
17. 練習問題のヒント
for(a <- 1 to 100; b <- 1 to 100; c <- 1 to 100) {
println((a, b, c))
}
単純に、a,b,cの組み合わせを出力するだけなら下記
for節の中に、a^2 == b^2 + b^2となる
条件をつけて下さい
18. 練習問題の回答
for(
a <- 1 to 100;
b <- 1 to 100;
c <- 1 to 100 if a * a == b * b + c * c
) {
println((a, b, c))
}
条件を付ける
21. try式による例外のスロー
scala> val n = 3
n: Int = 3
scala> val half = if (n % 2 == 1) {n / 2}
else {throw new RuntimeException("n must be even")}
half: Int = 1
scala> val half = if (n % 2 == 0) {n / 2}
else {throw new RuntimeException("n must be even")}
java.lang.RuntimeException: n must be even
... 27 elided
条件にマッチしたので例外投げない
条件にマッチしない
ので例外を投げる
値を返す
例外を返す
22. 例外のキャッチ
import 色々
try{
val f = new FileReader(“input.txt”)
} catch {
case ex: FileNotFoundException => {ファイル無しerror処理}
case ex: IOException => {I/O error処理}
} finally {
file.close()
}
最後に必ず呼ばれる処理を書く。
例外が呼ばれた場合でも、
必ずファイルは閉じる。
例外のキャッチと処理
27. match式
マッチ対象の式 match {
case パターン1 [if ガード1] => 式1
case パターン2 [if ガード2] => 式2
case ...
case パターンN => 式N
}
scala> val one = 1
one: Int = 1
scala> one match {
| case 1 => "one"
| case _ => "other"
| }
res0: String = one
具体例
一般例
1にmatchしたらoneを返す。
それ以外ならotherを返す。
29. breakとcontinueは無い
var i = 0
var foundIt = false
while (i < args.length && !foundIt) { // 引数の方が長く、見つかって無
い
if (!args(i).startsWith(“-”)) { // 文頭が”-”ではない
if (args(i).endWith(“.scala”)) // 文末が”.scala”である
foundIt = true // 見つかった!!
}
i = i + 1
} 命令型の書き方だと
30. breakとcontinueは無い
def searchfrom(i: Int): Int =
if (i >= arts.length) -1
else if (args(i).startsWith(“-”)) searchFrom(i + 1)
else if (args(i).endWith(“.scala”) i
else searchFrom(i + 1)
val i = searchFrom(0)
文頭が”-”なので、
iに1を足して最チャレンジ(再帰)
文末が”.scala”では無いので、
iに1を足して最チャレンジ(再帰)
ループ処理は、
再帰処理とvalのみを使う
31. 変数のスコープ
val a = 1;
{
println(a)
}
1と表示される
val a = 1;
{
val a = 2
println(a)
}
println(a)
2
1
と表示される
val a = 1;
{
println(a)
val a = 2
println(a)
}
error
変数のスコープは{}等で切り替わる。
※中括弧以外で切り替わるのある??
forward
reference
extends over
definition of
value a
32. 命令形から関数型へ1
scala> def printArgs(args: Array[String]): Unit = {
| var i = 0
| while (i < args.length) {
| println(args(i))
| i += 1
| }
| }
printArgs: (args: Array[String])Unit
scala> printArgs(Array("zero", "one", "two"))
zero
one
two
標準出力という副作用
varは控えよう!