Swift 5周年
Swift Version 1のリリースとほぼ同時期のSoftware Desig 2014年12月号から続いてきた本連載ですが、
WWDC19はそれを再確認する場でもありました。とくに図1のSwiftUIというSwiftオンリー、

今回ではSwiftはどう進化してきたかを振り返り、
Date | Version | Comment |
---|---|---|
2014-09-09 | 1. | |
2014-10-22 | 1. | |
2015-04-08 | 1. | |
2015-09-21 | 2. | |
2015-10-21 | 2. | |
2016-03-21 | 2. | Open-Sourced |
2016-09-13 | 3. | Playgrounds for iPad |
2017-09-19 | 4. | |
2018-03-29 | 4. | |
2018-09-17 | 4. | |
2019-03-25 | 5. | ABI Stability |
What's in
何につけ進化について調べるということは、
"""
かつてSwiftで複数行にわたる文字列リテラルを記述する方法は用意されておらず、
var text = [
"zero",
"one",
"two",
"three"
].joined(separator:"\n")
のようにする必要がありましたが、
var text = """
zero
one
two
three
"""
と書けるようになりました。
try! Swift // you couldn't
try! Swiftといえば今ではもっとも有名なSwiftカンファレンスですが、
try {
// 例外が発生する可能性がある処理
} catch {
// 例外が発生した場合の処理
}
という書き方をしますが、try
をブロックの指定ではなく例外をthrow
する関数を明示するために使った点。throws
が定義された関数を呼び出す際には必ずtry
かtry!
かtry?
しなければならないため、
let result = try? throwable()
のように例外が発生したことだけわかればいい場合は、catch
を不要にもできる点が便利です。
indirect
enum
連結リストの実装を考えてみます

Cであれば、
struct linkedlist {
VALUE_T value;
struct linkedlist *link;
};
といったところでしょうか。ところがこれと同じことを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
に変えるとエラーはなくなり、me.
のような循環参照も許されてしまいます。Swift 2でindirect
指定が加わったことにより、
indirect enum LinkedList<T> {
case Some(T, LinkedList<T>)
case Nil
}
What's out
次に出て行ったものを見てみましょう。
++ --
かつてはSwiftにも++
および--
演算子が存在しましたが、++
するのは得策ではないでしょう。
prefix func ++<N:Numeric>(_ n:inout N)->N {
n += 1
return n
}
postfix func ++<N:Numeric>(_ n:inout N)->N {
let r = n
n += 1
return r
}
引数のvar
かつてのSwiftでは、var
指定することで次のような書き方が許されていました。
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
になりました。どうしても引数を書き換えたいというのであれば、
func fact(_ n:Int) -> Int {
var r = 1
var t = n
while 0 < t {
r *= t
t -= 1
}
return r
}
Cスタイルのfor;;
ループ
ここまで来れば、
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
相当の、
Nothing more to take away
Swiftの進化を最も特徴づけているのは、
「完璧なのは、
次回予告
次回はいよいよ最終回。プログラミングという行為の未来を、
本誌最新号をチェック!
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の実行環境(基礎編)