ループから抜け出すための3つ(またはそれくらい)のオプションがあります。
合計が1000を超えるまで数値を合計したいとします。
var sum = 0
for (i <- 0 to 1000) sum += i
(合計> 1000)のときに停止する場合を除きます。
何をすべきか?いくつかのオプションがあります。
(1a)テストする条件を含む構成を使用します。
var sum = 0
(0 to 1000).iterator.takeWhile(_ => sum < 1000).foreach(i => sum+=i)
(警告-これは、takeWhileテストとforeachが評価中にインターリーブされる方法の詳細に依存するため、実際には使用しないでください!)。
(1b)forループの代わりに末尾再帰を使用し、Scalaで新しいメソッドを作成するのがいかに簡単かを利用します。
var sum = 0
def addTo(i: Int, max: Int) {
sum += i; if (sum < max) addTo(i+1,max)
}
addTo(0,1000)
(1c)whileループの使用にフォールバックします
var sum = 0
var i = 0
while (i <= 1000 && sum <= 1000) { sum += 1; i += 1 }
(2)例外をスローします。
object AllDone extends Exception { }
var sum = 0
try {
for (i <- 0 to 1000) { sum += i; if (sum>=1000) throw AllDone }
} catch {
case AllDone =>
}
scala.util.control.Breaks
(2a)Scala 2.8以降では、これはC/Javaからのよく知られた古いブレークによく似た構文を使用してすでにパッケージ化されています。
import scala.util.control.Breaks._
var sum = 0
breakable { for (i <- 0 to 1000) {
sum += i
if (sum >= 1000) break
} }
(3)コードをメソッドに入れ、returnを使用します。
var sum = 0
def findSum { for (i <- 0 to 1000) { sum += i; if (sum>=1000) return } }
findSum
これは、私が考えることができる少なくとも3つの理由から、意図的に簡単になりすぎないようにしています。まず、大きなコードブロックでは、「continue」および「break」ステートメントを見落としたり、実際よりも多かれ少なかれ脱出していると考えたり、実行できない2つのループを破る必要があります。とにかく簡単に-したがって、標準的な使用法は便利ですが、問題があるため、コードを別の方法で構造化する必要があります。第二に、Scalaにはおそらく気付かないようなあらゆる種類の入れ子があるので、何かから抜け出すことができれば、コードフローがどこで終わったか(特にクロージャーの場合)におそらく驚かれることでしょう。第三に、Scalaの「ループ」のほとんどは実際には通常のループではなく、独自のループを持つメソッド呼び出しです。ループのように、「ブレーク」などが何をすべきかを知るための一貫した方法を思い付くのは難しいです。したがって、一貫性を保つために、より賢明なことは、「休憩」をまったく持たないことです。
注:これらすべての機能に相当するものがあり、値を所定の位置で変更するのではsum
なく、の値を返します。これらはより慣用的なScalaです。ただし、ロジックは同じままです。(などにreturn
なりreturn x
ます)。