書いて覚えるSwift入門

第9回 Swift 2で,何が変わるのか?

この記事を読むのに必要な時間:およそ 5 分

収穫の秋

毎年9月末の「秋のApple祭り」は,毎年恒例になった感があります注1)。新しいiOS,新しいiPhone,そして新しいXcode。iOS 9は日本時間9月17日未明にリリースされ,Xcode 7もそれとほぼ同時にApp Storeでの配布が開始されました。同時にリリースされる予定だったwatchOS 2のリリースこそ5日遅れましたが,あとは9月25日にiPhoneが届けば祭りもクライマックスといったところでしょうか。本稿が読者のみなさんの手に届くころには,iOS 9もiPhone 6s/6s plusもすっかり馴染んでいることでしょう。

しかしXcode 7,そしてSwift 2はどうでしょうか? 以前紹介したとおり,今年中にはAppleはSwiftのオープン化を公約しています。Swift 2に習熟するには絶好の期間かもしれません。

注1)
この連載は,Software Design 2015年11月号に掲載されたものです。

そのXcode,本物ですか?

そのXcodeですが,気になるニュースが1つ。中国で改竄され配布された通称XcodeGhostで開発,デプロイされたアプリが,マルウェアに感染した状態でApp Storeに登場したのです。

Apple IDさえあればβ版も無料で入手でき,ましてや安定版がMac App Storeから無料で入手できるXcodeのパチモノをわざわざ使うなんて一見ありえなさそうですが,さすがGreat Firewall of Chinaの向こうだけあって,かの国ではAppleの公式サーバとの接続も日本のように安定しているとも言えず,よって(違法に)二次配布するサイトも点在しているようです。飛行機を乗っ取るために空港を乗っ取るようなもので,不謹慎ながら感嘆を禁じ得ませんでした。

Appleもこの件に関しては,異例の注意喚起を行っています。

そのXcodeが本物か否かは,Terminal.appでspctl --assess --verbose /Applications/Xcode.appを実行すればOKです。Xcodeの巨大さゆえ,コマンドが終了するのにしばらく待たされるのですが,問題なければ

/Applications/Xcode.app: accepted
source=Mac App Store

のようにacceptedを含んだ表示が出るはずです。

Apple「すべてのSwift 1.xプロジェクトを,生まれる前に消し去りたい」

それでは気を取り直して本題へ。iPhone 6sのキャッチコピーは,「唯一変わったのは,そのすべて。」だそうですが,Swiftの変貌ぶりはそれどころではありません。なにしろSwift 1.xのコードが全然そのまま動かないのですから。Python 2.xとPython 3.xは別言語ですが,Swift 1.xとSwift 2.xの別言語ぶりはそれをも凌駕します。Python 3の普及が遅れている一番の理由はまさにそこ,「同じ言語じゃない」という点にあるのですが,AppleはそれをXcodeでひっくり返しました。Swift 1.xで書かれたプロジェクトを開くと,XcodeがSwift 2.xに翻訳してくれるのです。その一部始終は前々第7回に紹介したとおりですが,まるで「すべてのSwift 1.xプロジェクトを,生まれる前に消し去りたい」といわんばかりのこの機能には「そんな祈りが叶うとすれば,それは時間干渉なんてレベルじゃない。因果律そのものに対する反逆だ」とインキュベーターでなくとも叫びたくもなるというものです。Python 3どころかPerl 6とか,「人類には早すぎる言語」との付き合いが浅からぬ筆者には,「さすがApple!おれたちにできない事を平然とやってのけるッそこにシビれる!あこがれるゥ!」という冷やかしすら無理で,ただ伏してメメタァするしかありませんでした。

前々回で私は「Swift 2への移行は正式版が出た後で,ただしSwift 2正式化以後はSwift 1の後方互換性サポートも捨てるのがよさそうです。筆者がGitHubに上げているプロジェクトはそうするつもりです」と述べましたが,ほぼそのようになりました。Swift 2正式版がXcodeとともにリリースされてまだ一週間も経っていないのに,筆者はすでにSwift 1がどうだったか思い出せなくなりつつあります。

What's new in Swift 2

というわけで,後方非互換性はXcode 7の力であっさりと乗り越えてしまいましたが,これからがやっと俺たちの戦い。Swift 2は何が変わったのでしょうか? 完全に書き直されたThe Swift Programming Languageでそれを追うのは,サン・ピエトロ寺院を見てコロッセオがどうだったかを思い起こすほど難しいかもしれません(コロッセオは石切場だったのです。これ豆)。筆者の場合,Swift 1から2への変遷を追うのに一番ありがたかったのはWWDC 2015のビデオ,What's new in Swiftでした。本稿でもそれを改めて駆け足で追いかけた後,くり紹介していく予定です。逆に,println()からprint()など,Xcode 7が自動で片付けてしまう変更点に関しては,軽く触れるにとどめます。

最低限文化的なenum

Swiftのenumは,enumというよりむしろunion(共用体)に近いもので,本当はSwift 1の頃からもっとバリバリ使いたかったのですが,classstructと比べると微妙に使いづらいものでした。

デフォルトのdescription debugDescriptionが直感的に

たとえば,

enum Langs {
    case C, Cplusplu, ObjectiveC, Swift
}

というenumがあったとして,print(Langs.Swift)はそのままではそっけなく(Enum Value)と表示されるだけでした。Swiftと表示させるためには,いちいち,

extension Langs : Printable {
  var description: String {
    switch self {
    case C:
          return "C"
        case Cplusplus:
          return "C++"
        case ObjectiveC:
          return "Objective-C"
        case Swift:
          return "Swift"
      }
  }
}

などという具合にdescriptionプロパティを定義しておく必要があったのですが,これと同様のことを自動でやってくれます。

総称型enumがまともに

Swift 1では次のコードがクラッシュしていました。

enum Either<L,R> {
    case Left(L)
    case Right(R)
}

総称型のEnumでは型変数が1つしか取れなかったので,

enum Optional<T> {
  case None
  case Some(T)
}

は定義できてもEitherのような型は作れなかったのですが,やっと作れるようになりました。

再帰的enumが可能に

Swift 1では,これもだめでした。

enum Cons<T> {
    case Nil
    case Atom(T)
    case Pair(Cons, Cons)
}

enumは値型(value type)なので,「固定的なサイズを持たなければならないのに,自己参照していては無限にメモリが必要になってしまう」とはSwiftのパパ,Chris Lattnerの弁。「今のデバイスでは無理。まあ来年あたりなら」というジョークが見事に滑っていましたが,indirectを次のようにつけることで再帰的enumが実現可能になりました図1)。

enum Cons<T> {
    case Nil
    case Atom(T)
    indirect case Pair(Cons, Cons)
}

図1 再帰的enum

図1 再帰的enum

もしくは,

indirect enum Cons<T> {
    case Nil
    case Atom(T)
    case Pair(Cons, Cons)
}

ここまでそろっていたなら,筆者もswiftjsonをenumベースで実装したんですがねえ……。

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。

コメント

コメントの記入