- 更新日: 2014年9月23日
- Swift & iOS
RunSwiftでSwift入門
iOS 開発用の新しいプログラミング言語 Swift を、ブラウザで実行して試せる RunSwift – Try Swift in the Browser というウェブサービスを発見しました。それで Swift の触りだけでも勉強しようと思ったら、RunSwift のサンプルで書いてある Swift コードがいきなり難しかったので、とりあえずそれを解読した。
RunSwift デフォルトのサンプルコード
1 2 3 4 5 6 7 8 9 10 11 |
// Project Euler #1 Solution in Swift func anyMultipleOf(value: Int, numbers: [Int]) -> Bool { return numbers.reduce(false) { any, number in return any || ((value % number) == 0) } } let sum = [Int](1..<1000).filter() { anyMultipleOf($0, [3, 5]) }.reduce(0) { $0 + $1 } println(sum) |
コンパイル後の実行結果。
1 2 3 |
233168 |
print デバッグ
ぱっと見よく分かんないので、以下のように print デバッグを差し込んで計算の流れを確認。filter に渡す配列も1から9までに限定しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// Project Euler #1 Solution in Swift func anyMultipleOf(value: Int, numbers: [Int]) -> Bool { return numbers.reduce(false) { any, number in print(value) print(" % ") print(number) print(" : ") println(any || ((value % number) == 0)) return any || ((value % number) == 0) } } let sum = [Int](1..<10).filter() { anyMultipleOf($0, [3, 5]) }.reduce(0) { $0 + $1 } println(sum) |
コンパイル後の実行結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
1 % 3 : false 1 % 5 : false 2 % 3 : false 2 % 5 : false 3 % 3 : true 3 % 5 : true 4 % 3 : false 4 % 5 : false 5 % 3 : false 5 % 5 : true 6 % 3 : true 6 % 5 : true 7 % 3 : false 7 % 5 : false 8 % 3 : false 8 % 5 : false 9 % 3 : true 9 % 5 : true 23 |
これで、どういう流れでプログラムが実行されるか分かりました。filter に渡されるブロックが真を返す要素に対してのみ、reduce 以降が実行される。上の例では…
3 + 5 + 6 + 9 = 23
となるわけだ。
Swift のクロージャ
RunSwift のデフォルトのコードはクロージャがばりばり使ってあるので、クロージャを理解してないと難しいです。
Swiftでは中括弧{}で囲まれたコードブロックは事実上全てクロージャとなる。 このとき、引数・戻り値と、本体の処理の間に「in」を書くことで、この2つの部分を区別する。
なるほどなー。Ruby での { |b1, b2| some_code } が、Swift の場合 { b1, b2 in some_code } になるのですね。
インラインのclosureは引数名すら省略可能。
その場合は$0、$1、$2・・・と先頭の引数から順にアクセスできる。
おおお、さらにクロージャは引数名も省略できて、$0, $1, $2 でアクセスできると…。なるほど…。これで、謎は半分以上解けました。
Swift の filter, reduce
filter, reduce については、以下あたりが参考になります。
Swift: filter、map、reduce を使う – Sarabande.jp
いい豆作ろう -GOOD BEANS-: [Swift, iOS]Swiftのmapとreduceについて書いてみた
filter は Ruby でいうところの select, reduce は inject みたいなものでしょう。filter は渡されたブロックが真を返す要素のみ抽出する。reduce は初期値をブロックの評価値で上書きしていく。
let sum の右辺部分は、Ruby で書くと以下のような感じかと思います。
1 |
sum = (1...1000).select { |i| any_multiple_of(i, [3, 5]) }.inject(0) { |total, n| total + n } |
型情報の指定以外は、Swift と Ruby は結構似たような感じで書けるみたい。以上簡単ですが、Swift に少しだけ入門してみた。以前ちょっとだけ勉強して挫折してしまった Objective-C に比べると、Swift の文法は読みやすいシンタックスだと感じます。この言語ならモチベーションを保って学習できそう。
- Swift & iOS の関連記事
- WKWebView/UIWebViewでウェブページが真っ白
- Unityのインストールと初期設定
- WKWebView/UIWebViewでNavigation Barの下にウェブページが隠れるのを回避
- SwiftでArray(配列)などをシャッフル
- Navigation Controllerで画面遷移させるSwiftコード
- Swiftでタップ/スワイプのイベント処理実装・UITapGestureRecognizerとUISwipeGestureRecognizer
- UIPageViewController画面下部のUIPageControlを非表示にする
- Swiftのバージョン確認・REPL実行
- Xcode7.0アップデートで遭遇した課題2つ
- 正規のXcodeかどうかチェック(XcodeGhostマルウェア騒動)
Leave Your Message!