0, 1, … , 100までの数字の和を求める
var i = 0
var sum = 0
while(i <= 100) {
sum += i
i += 1
}
2つのvarが登場しているため不安が残る。少し安全に書くには以下のように関数内に処理を閉じ込めると良い。
def aseries(limit:Int) = {
var i = 0
var sum = 0
while(i <= limit) {
sum += i
i += 1
}
sum
}
aseries(100)
関数の中で関数を定義しScalaらしいコードに。
def aseries(limit:Int) = {
def loop(i:Int) : Int = if(i <= limit) i + loop(i+1) else i
loop(0)
}
aseries(100)
このような形の再帰は末尾再帰と呼ばれ、Scalaコンパイラは自動的にwhile文を使った式に最適化してくれる。本当に末尾最適化されているか確認するためには、@tailrec
アノテーションをつけておくこと。末尾再帰最適化できない場合コンパイルエラーになる。
@tailrec
def aseries(limit:Int) = {
def loop(i:Int) : Int = if(i <= limit) i + loop(i+1) else i
loop(0)
}
aseries(100)
for loopはおなじみ。
var sum = 0
for(i <- 0 to 100)
sum += i
より短く,
var sum = 0
(0 to 100) foreach (sum += _)
varの使用を避けてより関数型言語らしく
(0 to 100) reduce (_ + _)
(0 to 100) fold(0)(_ + _) // 初期値を明示したい場合