Allow (most) keywords in member references
01 何が問題だったのか
SE-0005 によって、Objective-C のAPIをSwiftに取り込む際には enum のケース名がlowerCamelCaseに変換されるようになりました。その結果、Default や Private、Repeat のように従来は問題なかった名前が、Swiftのキーワードと衝突するケースが一気に増えました。
宣言側ではバッククォートで回避できる
型の宣言側では、キーワードと衝突するケース名をバッククォートで囲めば従来どおり扱えます。
enum UITableViewCellStyle : Int {
case `default`
case value1
case value2
case subtitle
}
enum SCNParticleImageSequenceAnimationMode : Int {
case `repeat`
case clamp
case autoReverse
}
Objective-C由来の定数は UITableViewCellStyleDefault や SCNParticleImageSequenceAnimationModeRepeat のように元々長い名前を持つため、宣言側でバッククォートを付けること自体はさほど苦になりません。
利用側でバッククォートが毎回必要になる
問題は利用側です。メンバアクセスの . の後ろにキーワードと同名のケースを書くと、やはりバッククォートで囲まなければならず、呼び出しの見た目が一気に煩雑になります。
let cell = UITableViewCell(style: .`default`, reuseIdentifier: nil)
particleSystem.imageSequenceAnimationMode = SCNParticleImageSequenceAnimationMode.`repeat`
Objective-C APIを普通に使うだけの利用者が、あらゆる呼び出し箇所でバッククォートを書かされるのは、SwiftのAPI Design Guidelinesが目指す「読みやすい呼び出し側」の理念に反します。同様の問題は、SE-0001 が引数ラベル位置で解決済みでしたが、メンバ参照の位置では未解決のまま残っていました。
02 どのように解決されるのか
メンバアクセスの . の直後では、ごく一部を除くほぼすべてのキーワードをバッククォートなしで書けるようにします。. に続く位置では、文法的にそこに現れるのは識別子しかありえないため、キーワードをそのまま識別子として解釈しても曖昧さが生じません。
バッククォートを外せる
先ほどの例は次のように、ごく自然な形で書けるようになります。
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
particleSystem.imageSequenceAnimationMode = SCNParticleImageSequenceAnimationMode.repeat
Objective-C由来の enum に限らず、Swiftで定義した型のメンバであっても、キーワードと同名であれば同じように . の後ろでバッククォートを省略できます。
除外されるキーワード
言語上特別な意味を持つ self / dynamicType / Type / Protocol は引き続き除外されます。これらは . の後ろでも文法的・意味的に特別扱いされるため、メンバ名として素直に扱うわけにはいきません。これらをメンバ名として使いたい場合は、従来どおりバッククォートが必要です。
なお、ここで挙げた除外キーワードの一覧はあくまで当時の言語仕様に追従するもので、Swiftの進化に合わせて変化しうる点には注意してください。
既存コードへの影響と移行
この変更は純粋な緩和であり、既存コードの挙動は変わりません。今までバッククォートを付けて書いていたコードはそのまま動き続けます。コンパイラはSE-0001と同様に、不要になったバッククォートに対して警告とFix-Itを提示できるため、機械的にコードを整理することも可能です。