Xcode 12と合わせて先日公開されたSwift 5.3には、マルチパターンcatch
句、暗黙のself
の可用性向上など、構文レベルでの重大な新機能がいくつも含まれている。さらにSwift開発チームは、特にSwiftUIを使用した場合のランタイムパフォーマンス向上や、開発者エクスペリエンスの向上にも取り組んでいる。
Swift 5.3ではひとつのcatch
句に複数のパターンを指定できるようになり、do try/catch
によるエラー処理の便宜性が向上した。例えば、次のような記述が可能になる。
do {
try performTask()
} catch TaskError.someRecoverableError {
recover()
} catch TaskError.someFailure(let msg),
TaskError.anotherFailure(let msg) {
showMessage(msg)
}
また、言語をより自然に使用できるようにする機能として、enum
型にComparable
への適合性をシンセサイズできるようになった。これにより、任意の比較演算子をenum
に適用して、case
の宣言順に従った値比較を行うことが可能になる。例えば、次のように記述することができる。
enum Membership : Comparable {
case premium(Int) // <
case preferred // <
case general
}
let planA = Membership.premium
let planB = Membership.general
if planA < planB {
...
}
[ .general, .premium, .preferred ].sorted()
Swift 5.3では、これまで使用できなかったEscaping Closureなどにおいても、参照サイクルを生成するリスクがなければ暗黙のself
を使用することができる。具体的にはこれは、self
が値型の場合だ。self
がstruct
のような参照型であれば、参照サイクルは発生しないので、次のように安全に記述することが可能になる。
struct Test {
var x = 0
func execute(_ work: @escaping () -> Void) {
work()
}
func method() {
execute {
x += 1 // instead of: self.x
}
}
}
同じく、上記スニペットのclass
ベース置き換えバージョンである以下のコードのように、クロージャのキャプチャリストでself
を参照するなどの方法でユーザが自身の意図を明確にしているケースにも、このルールが適用される。
class Test {
var x = 0
func execute(_ work: @escaping () -> Void) {
work()
}
func method() {
execute { [self] in
x += 1 // instead of: self.x
}
}
}
これらを含む多くの変更に加えて、Swift 5.3では、バイナリコードのサイズや実行時のメモリサイズも改善されている。Appleの計測によると、これによってコードサイズが30~40パーセント、ヒープサイズが60パーセント、それぞれ削減される。当然ながら、これらの結果は対象とするコードや使用パターンに強く依存するため、実際のマイレージはこれと異なる可能性がある。重要なのは、Appleによると、これによってSwiftで記述されたアプリケーションのヒープメモリ使用量が、同等のObjective-Cコードよりも少なくなると期待されることだ。
開発者エクスペリエンスの面では、Swift 5.3ではクロージャに関わる連鎖メソッドクラス、複数行に渡る関数引数やパラメータやコレクション要素、複数行に渡るif
やguard
やwhile
条件などにおけるインデンテーションが改善されている。また、関数内で同じシンボルを繰り返し使用する場合のコード補完が速くなった。
さらに、ファイル間での処理重複の回避、変更されていないコードの識別の向上などにより、インクリメンタルコンパイルも高速化している。全体として、他のライブラリからインポートしたプロパティや関数を多数使用する型の処理が高速になると同時に、宣言順やネストによる影響が少なくなった。
ツーリングに関する最後の注意として、Swift 5.3では多くのケースで、特にSwiftUIコードにおいて診断が改善されている。
Swift 5.3の変更点をここですべてを取り上げるには数が多すぎるので、詳細については公式リリース発表で確認して頂きたい。