Swift言語ガイド 第5章 制御の流れ
for-in ループ
- 数のレンジに使う例。
for i in 1...5 {
println( "5の倍数は \( i * 5 )" )
} - もしレンジの個々のインデックス値が不要であれば、アンダースコアにすることもできる。
let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
println( answer ) - 配列に使う例
let names = [ "ジョン", "ポール", "ジョージ", "リンゴ" ]
for name in names {
println( "こんにちは、\( name )。" )
} - ディクショナリに使う例。この場合、インデックスは
(key, value)
のタプルになる。ディクショナリは順不同なので、定義した順に出てくるとは限らないことに注意。
let numberOfLegs = [ "クモ": 8, "アリ": 6, "ネコ": 4 ]
for ( animalName, legCount ) in numberOfLegs {
println( "\( animalName ) の足は \( legCount ) 本。" )
} - 文字列中の文字に使う例
for character in "こんにちは" {
println( character )
}
for ループ
- C などに見られるのと同じ、条件とインクリメントでループする形。ループの1回が終わるごとにカウンターを増やしながら、特定の条件になるまでループを繰り返す。
for var i = 0; i < 3; ++i {
println( i )
} - この形を一般形は以下。ちなみに、初期化、終了条件、インクリメントの部分にかっこは不要。
for 初期化; 条件; インクリメント {
文
} - これは以下と等価。
初期化
while 条件 {
文
インクリメント
} - 初期化式に現れた定数や変数は
for
ループのスコープ内でだけ有効である。もしインデックス値の最後の値をfor
ループの後に参照したい場合は、ループのスコープが始まる前にインデックスを宣言しておかなければならない。
var i: Int
for i = 0; i < 3; ++i {
println ( i )
}
println( "インデックスの最終値は \( i )" )
while ループと do-while ループ
while
ループは、ある条件がfalse
になるまで文の集合を繰り返す。あらかじめループの回数がわからない場合などによく使われる。Swift ではwhile
とdo-while
の2つの形式があり、while
はループの最初で条件が評価され、do-while
はループの最後で条件が評価される。while
ループの一般形は以下。
while 条件 {
文
}do-while
ループの一般形は以下。
do {
文
} while 条件
条件文
- Swift には
if
文とswitch
文の2つがある。 - 条件部分にかっこがいらない。でもこれは
while
などでも同じ。 if
文はelse if
でチェイン可能。switch
文ではdefault
は必須であり、必ず最後になければならない。case
はbreak
しなくとも1つの実行で完了する。下のcase
に移りたい場合はfallthrough
キーワードを使う。詳しくは後述。- それぞれの
case
は最低1つの実行文がなければならない。 - 1つの
case
に2つ以上の値を書く場合はコンマで分ける。複数行になってもよい。
switch 条件式 {
case 値1,
値2:
実行文
default:
実行文
} case
は範囲でもよい。
let count = 3_000_000_000_000
let countedThings = "天の川の星の数"
var naturalCount: String
switch count {
case 0:
naturalCount = "no"
case 1...3:
naturalCount = "a few"
case 4...9:
naturalCount = "several"
case 10...99:
naturalCount = "tens of"
case 100...999:
naturalCount = "hundreds of"
case 1000...999_999:
naturalCount = "thousands of"
default:
naturalCount = "millions and millions of"
}- 1つの
switch
文の中でタプルを使えば、複数の値をテストすることができる。それぞれのタプルの要素は別々の値のレンジに対してテストできる。アンダースコアを使えば、どんな値にもマッチ可能。
let somePoint = ( 1, 1 ) // ( Int, Int ) のタプル
switch somePoint {
case ( 0, 0 ):
println( "( 0, 0 ) は座標の原点。" )
case ( _, 0 ):
println( "( \( somePoint.0 ), 0 ) は X 軸上にある。" )
case ( 0, _ ):
println( "( 0, \( somePoint.1 ) ) は Y 軸上にある。" )
case ( -2...2, -2...2 ):
println( "( \( somePoint.0 ), \( somePoint.1 ) ) は箱の中にある。" )
default:
println( "( \( somePoint.0 ), \( somePoint.1 ) ) は箱の外にある。")
} - 複数の
case
が重なってもよい。そういう場合は、上から調べて最初にマッチしたcase
が選択される。 - 値バインディング(Value Bindings)と呼ばれる一時的な定数や変数へのバインディングができ、そうすればその定数や変数を実行文で使用できる。
let anotherPoint = ( 2, 0 )
switch anotherPoint {
case ( let x, 0 ):
println( "X軸上で X の値は \( x )" )
case ( 0, let y ):
println( "Y軸上で Y の値は \( y )" )
case let ( x, y ): // これがキャッチオールの役目をするので default はなくてもよい。
println( "( \( x ), \( y ) ) というどこか。")
} switch
のcase
は、さらにwhere
句によって付加的な条件をチェックすることができる。
let yetAnotherPoint = ( 1, -1 )
switch yetAnotherPoint {
case let ( x, y ) where x == y:
println( "( \( x ), \( y ) ) は x == y の線上にある。" )
case let ( x, y ) where x == -y:
println( "( \( x ), \( y ) ) は x == -y の線上にある。" )
case let ( x, y ):
println( "( \( x ), \( y ) ) はどこか別の場所。")
}
制御移動文 Control Transfer Statements
continue
文は、ループでやっていることを止め、次のループに移動する。for
ループのインクリメントがある場合はインクリメントは評価される。スキップされるのは、ループの実行文の部分だけである。break
文は、制御の流れをコントロールする文全体をただちに終わらせる。break
文はswitch
文かループ制御文の中に使うことができ、それ以降の実行を終了させる。switch
文であれば、制御をswitch
文の閉じかっこ}
の次に移動させるし、ループであればループの閉じかっこ}
の次に移動させる。無視させたい(つまり何もしない)case
のところに使うこともできる。これは単にcase 条件句: break
と書けばよい。この場合、分岐は一致し、break
文によってただちにswitch
文を抜け出す。
let numberSymbol: Character = "三"
var possibleInteger: Int?
switch numberSymbol {
case "1", "一":
possibleInteger = 1
case "2", "二":
possibleInteger = 2
case "3", "三":
possibleInteger = 3
case "4", "四":
possibleInteger = 4
default:
break
}fallthrough
文は、C のように複数のケースを実行させたい時(下に行きたい時)に使う。- ラベル付き文はラベル名に続けてコロンをつけたループ文や
switch
文である。ラベルを使えるのはbreak
文かcontinue
文に続けてラベル名を指定する場合らしいが、これは文法編を参照のこと。さしあたり必要性を感じないので深く追求はしない。