書いて覚えるSwift入門

第51回 Swiftの5年間を振り返る

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

Swift 5周年

Swift Version 1のリリースとほぼ同時期のSoftware Desig 2014年12月号から続いてきた本連載ですが,次回で終了します。ソースコード非互換な変更もいとわなかったSwiftも,Version 5をもってABIも安定化され,言語として一応の完成を見たというのがその一番の理由です。

WWDC19はそれを再確認する場でもありました。とくに図1SwiftUIというSwiftオンリー,すなわちObjective-Cからはもはや使えないFrameworkは「変わらぬ保証」があってはじめて成立すると言っても過言ではありません。

図1 SwiftUI

図1 SwiftUI

今回ではSwiftはどう進化してきたかを振り返り,最終回である次回で今後どう進化していくのかを考察することにしましょう表1)⁠

表1 Swiftのバージョンと環境側の対応

DateVersionComment
2014-09-091.0
2014-10-221.1
2015-04-081.2
2015-09-212.0
2015-10-212.1
2016-03-212.2Open-Sourced
2016-09-133.0Playgrounds for iPad
2017-09-194.0
2018-03-294.1
2018-09-174.2
2019-03-255.0ABI Stability

What's in

何につけ進化について調べるということは,その過程で何が入り何が出たか調べることを意味します。まずは入ったものを見ていきましょう。

"""

かつてSwiftで複数行にわたる文字列リテラルを記述する方法は用意されておらず,

Swiftの例

var text = [
    "zero",
    "one",
    "two",
    "three"
].joined(separator:"\n")

のようにする必要がありましたが,Swift 4以降ではPython同様,

Swift 4の例

var text = """
    zero
    one
    two
    three
"""

と書けるようになりました。

try! Swift // you couldn't

try! Swiftといえば今ではもっとも有名なSwiftカンファレンスですが,実はSwift 1には存在しない概念でした。多くの言語で例外処理は,

JavaScriptの例

try {
    // 例外が発生する可能性がある処理
} catch {
    // 例外が発生した場合の処理
}

という書き方をしますが,Swiftの特徴はtryをブロックの指定ではなく例外をthrowする関数を明示するために使った点。throwsが定義された関数を呼び出す際には必ずtrytry!try?しなければならないため,どこで例外が発生したかがわかりやすいうえ,

Swiftの例

let result = try? throwable()

のように例外が発生したことだけわかればいい場合は,catchを不要にもできる点が便利です。

indirect enum

連結リストの実装を考えてみます図2)⁠

図2 連結リスト

図2 連結リスト

Cであれば,

C言語の例

struct linkedlist {
    VALUE_T value;
    struct linkedlist *link;
};

といったところでしょうか。ところがこれと同じことをSwiftでやろうとすると……,

Swiftの例

struct LinkedList<T> {
    var value:T? = nil
    var link:LinkedList<T>? = nil
}

error: value type 'LinkedList<T>' cannot have a stored property that recursively contains itと怒られてしまいます。値型のstructではなく参照型のclassに変えるとエラーはなくなり,実装上もCなどと同じになりはするのですが,参照型だとme.link = linkのような循環参照も許されてしまいます。Swift 2でindirect指定が加わったことにより,次のように書けるようになりました。

Swift 2の例

indirect enum LinkedList<T> {
    case Some(T, LinkedList<T>)
    case Nil
}

What's out

次に出て行ったものを見てみましょう。

++ --

かつてはSwiftにも++および--演算子が存在しましたが,Swift 3でなくなりました。Swiftはカスタム演算子を実装できるので,次のようにすれば再定義が可能ではありますが,ヒューマンエラー++するのは得策ではないでしょう。

かつてのSwiftの例

prefix func ++<N:Numeric>(_ n:inout N)->N {
    n += 1
    return n
}

今のSwiftの例

postfix func ++<N:Numeric>(_ n:inout N)->N {
    let r = n
    n += 1
    return r
}

引数のvar

かつてのSwiftでは,引数をvar指定することで次のような書き方が許されていました。

かつてのSwiftの例

func fact(_ n:var Int) -> Int {
    var r = 1
    while 0 < n {
        r *= n
        n -= 1
    }
    return r
}

なお,var指定はinout指定とは異なることに注意してください。inoutの場合は呼び出し元も書き換わりますし,呼び出す際には&を変数名につけてその旨を明示する必要があります。

このようにinoutと紛らわしいうえ,エラーも誘発しやすいということで,inout指定されていないSwiftの引数はすべて(強いて言うなら)letになりました。どうしても引数を書き換えたいというのであれば,次のようにコピーを取ってからすればいいのですし。

今のSwiftの例

func fact(_ n:Int) -> Int {
    var r = 1
    var t = n
    while 0 < t {
        r *= t
        t -= 1
    }
    return r
}

Cスタイルのfor;;ループ

ここまで来れば,かつてのSwiftに,

for var i = 0; i < ary.count; i++ {
  let v = ary[i]
  // ...
}

という構文があったことも驚かないでしょう。もちろんこれは,

for v in ary {
    // ...
}

と書いたほうがずっとわかりやすいですし,一般的なfor(foo; bar; baz){ quux }

foo
while bar {
  quux
  baz
}

と書けるのですからなくても困りません。

foreach相当の,コレクションの各要素を順繰りに処理する構文を持つ言語ではCスタイルのforは避けるべきとされつつも廃止までしていないのに対し,バッサリ切ってしまうのがSwiftyですね。

Nothing more to take away

Swiftの進化を最も特徴づけているのは,何を加えたかではなく何を捨てたか。Swiftほど捨てっぷりがいいプログラミング言語を筆者は知りません。とくに構文は一度捨てると下位互換性は確実に失われるため,非推奨になっても居座り続け,捨てるためには別言語にするしかないというのがプログラミング言語業界の常識にすら感じますが,SwiftはあくまでSwiftだというところが不思議でもあります図3)⁠

図3 何も捨てない結果

図3 何も捨てない結果

「完璧なのは,これ以上付け加えるものがなくなったときではなく,これ以上取り除くものがなくなったとき」と言ったのはサン=テグジュペリだそうですが,その意味で5以降のSwiftから何かを取り除くのは格段に難しくなったのは確かです。

次回予告

次回はいよいよ最終回。プログラミングという行為の未来を,Swiftを通して考察する予定です。

Software Design

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

2019年8月17日発売
B5判/176ページ
定価(本体1,220円+税)

  • 第1特集
    気になるとこだけまとめて知りたいGoogle Cloud Platform
    開発・分析・人工知能のサービスを一挙解説
  • 第2特集
    ひとりで始めるPythonプログラミング入門
    コーディングと機械学習環境の作り方

著者プロフィール

小飼弾(こがいだん)

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

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

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