書いて覚えるSwift入門

第33回ゆくXくるX

iPhone Xの購入

本稿を読者のみなさんがお読みになるのは年末年始ですが、その1月前の執筆現在、今年出る予定のApple製品は、HomePodが延期されてあますところiMac Proだけとなりました。最大の目玉であるiPhone Xも、品不足で来年になるかと危惧したものの、筆者の手元に届いており(写真1⁠⁠、animojiがはかどっております図1⁠。

写真1 iPhone Xラインナップ
写真1 iPhone Xラインナップ
図1 animoji
図1 animoji

iPhone Xと言えばホームボタンがなくなったことと、⁠全画面-顔面センサー=鬼ディスプレイ」のほかにも、本体価格がついに$1,000の大台に乗ったことも話題となりました。ストレージ256GBの上位機種にいたってはMac Bookとほとんど値段が変わりません。それだけの価値はあるのでしょうか?

できることを列挙するのであれば、MacBookはiPhoneの足元にも及びません。iPhoneなら単体で接続できるLTEネットワークに接続するのにMacBookはほかのスマートフォンの力をテザリングで借りなければいけませんし、Face IDはおろかGPSさえ非搭載。カメラにいたってはビデオ会議用のしょぼいインカメラだけです。

しかし、MacBook――というよりMac――でなければできないことが1つ残っています。それがアプリケーションの開発。iPhoneの登場以来ずっと「そういうものだ」と思われてきましたが、その理由がハードウェアの能力不足でないことはiPadとSwift Playgroundsがすでに証明しています図2⁠。むしろXcode for iPadがまだないことのほうが不思議なぐらいです。

図2 Swift playgrounds
図2 Swift playgrounds

まだiOSデバイスはおろかMacにIntel入っていないころからApple製品と付き合ってきた筆者からすると、この状況は少々物足りない。さすがに電源を入れたらBASICインタプリタが立ち上がり、プログラムを打ち込まなければ使えない8ビットCPUの時代に戻れとは思いませんが、かつてあったHyperCard図3に相当するものがiPhoneにないことには少なからぬ物足りなさを感じています。

図3 なつかしのHyperCardをiPhone Xで
図3 なつかしのHyperCardをiPhone Xで

HyperCardの何が画期的だったかと言うと、プログラミングとオーサリングの境界をなくしたこと。データとコードが渾然一体となった「スタック」は、⁠製品」にするには滅法不向きでも、⁠動的コンテンツ」としてみた場合には最高で、それこそTwitterにつぶやく程度の気軽さでスタックを作っていたものです。

そのころよりコンピュータができることは飛躍的に増えました。市場も幾何級数的に大きくなりました。しかしそのことがかえってプログラミングというものの敷居を上げたのだとしたらなんと寂しいことでしょう。

筆者がSwiftを「買った」理由の1つは、ますます敷居が上がっていくようにも見えるプログラミングという行為を、⁠玄人」をも納得させつつ「素人」に少しでも取り戻そうとした点にあります。スマートフォンにしかできないことがこれだけ増えた今、そろそろPlaygrounds for iPhoneが欲しくなってきませんか?

Swift 4.1

前置きはこれくらいにして、本題に。Xcode 9とともにSwift 4が来たと思いきや、Swift 4.1の足音がすでに聞こえてきています。Swift 4.0とソースコード互換ではありますが、バイナリ互換ではない点は注意を要します。

正式リリースは来年前半とのことですが、すでにバイナリースナップショットが公式サイトより配布されており、それを使って変更点および新機能を検証できるようになっております。本記事では Ubuntu 16.04用のスナップショットで検証を行いました。

[SE-0157]:再帰的なプロトコル制約

Swift 4.1の一番の目玉はこれでしょう。プロトコル中のassociatedtypeの制約に、それ自身が使えるようになりますリスト1⁠。

リスト1 associatedtypeの利用方法の変更
protocol Sequence {
    associatedtype Element
    associatedtype SubSequence: Sequence
      where SubSequence.Element == Element,
            SubSequence.SubSequence == SubSequence
    // ...
}

protocol Collection: Sequence
    where Self.SubSequence: Collection {
    // ...
  }

筆者から見てSwiftの一番の欠点は、再帰型でした。たとえばSwift 1では、

enum List<T> { // Swift 2 or better
    case Nil
    indirect case Cons(T, List<T>)
}

のように、自分自身と同じ型のプロパティを内包した型さえ作れなかったのです。この状況はSwift 2で大きく前進したのですが、あくまで再帰的な型を作れるのは実体型であり、プロトコルで同様なことはできませんでした。

ご覧のとおり実例としてSwiftで欠かすことのできないSequenceSubSequenceが挙げられており(リスト1⁠⁠、これもたバイナリ非互換の一因かと思われますが、これらのプロトコルは今までどおり使えるのでソース互換は保たれていると認識しています。

[SE-0186]:プロトコル中におけるweakおよびunowned指定の禁止

メモリ管理をどうするかは実体型の問題であってプロトコルの問題ではなかったはずですが、Swift 4時点でリスト2のコードは問題なく動いていました。

リスト2 バージョンアップで動かなくなると予想されるコード
class A {}

protocol P {
    weak var weakVar: A? { get set }
    unowned var unownedVar: A { get set }
}

Swift 4.1以降は警告が発せられ、Swift 5からはエラーになります。

[SE-0185]:==および.hashValueの自動生成

リスト3で、Swift 4.1ではストアドプロパティがすべてEquatableの場合には==演算子が、Hashableの場合には加えて.hashValueが自動で定義されるようになります図4⁠。

リスト3 .hashValueの自動生成
struct Point<T:Hashable>: Hashable {
    let x: T
    let y: T
    init(_ x: T, _ y: T) {
        self.x = x
        self.y = y
    }
}
図4 実行結果
Point(3, 0) == Point(0, 3) // false
Point(3, 0) == Point(3, 0) // true
Point(3, 0).hashValue // -2942920663782199421

Protocol Extensionの導入により自動生成される演算子やメソッドやプロパティは格段に増えたのですが、この2つがまだ自動生成の対象になっていなかったのはよく考えてみると意外です。==はストアドプロパティがすべて==のときだけtrueで、hashValueはストアドプロパティの.hashValueを合成すれば生成できるというのはいわば自明だからです。

もちろんこれまでどおり手動で定義されたものはそちらが優先されるので、4.1が正式リリースされたら==.hashValueは削除してしまうのも一考かもしれません。==はとにかく.hashValueで適切なハッシュ関数を定義するのは案外難易度高いので。

次回予告

前半で昨今のプログラミング環境の敷居の高さをぼやきつつ、後半でプログラミング言語の詳細を紹介するというのは我ながら本末転倒感がありますが、次回はもう少しカジュアルに行く予定です。

Software Design

本誌最新号をチェック!
Software Design 2022年9月号

2022年8月18日発売
B5判/192ページ
定価1,342円
(本体1,220円+税10%)

  • 第1特集
    MySQL アプリ開発者の必修5科目
    不意なトラブルに困らないためのRDB基礎知識
  • 第2特集
    「知りたい」⁠使いたい」⁠発信したい」をかなえる
    OSSソースコードリーディングのススメ
  • 特別企画
    企業のシステムを支えるOSとエコシステムの全貌
    [特別企画]Red Hat Enterprise Linux 9最新ガイド
  • 短期連載
    今さら聞けないSSH
    [前編]リモートログインとコマンドの実行
  • 短期連載
    MySQLで学ぶ文字コード
    [最終回]文字コードのハマりどころTips集
  • 短期連載
    新生「Ansible」徹底解説
    [4]Playbookの実行環境(基礎編)

おすすめ記事

記事・ニュース一覧