Swift Digest
SE-0040 | Swift Evolution

Replacing Equal Signs with Colons For Attribute Arguments

Proposal
SE-0040
Authors
Erica Sadun
Review Manager
Chris Lattner
Status
Implemented (Swift 3.0)

01 何が問題だったのか

Swift の属性(@available@warn_unused_result など、@ で始まる宣言への注釈)のうち、いくつかは引数を受け取れます。しかし、この提案以前の Swift では、属性引数の「ラベル」と「値」を区切るために = が使われていました。

@available(*, unavailable, renamed="MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol

@warn_unused_result(mutable_variant="sortInPlace")
public func sort() -> [Self.Generator.Element]

@available(*, deprecated, message="it will be removed in Swift 3.  Use the 'generate()' method on the collection.")
public init(_ bounds: Range<Element>)

一方、Swift の他のラベル付き引数(関数呼び出しの引数ラベルや、辞書リテラルのキーと値の区切りなど)はすべて : を使います。属性の引数だけがこの一般則から外れた「例外」として = を使っていたため、言語全体の一貫性を損なっていました。

属性はこの先も語彙が広がっていくことが見込まれており、そのたびに = を使う一箇所だけ特殊な書式が増えていくのは望ましくありません。小さな修正ですが、Swift 全体のシンタックスを揃えておく価値のある不整合でした。

02 どのように解決されるのか

属性引数で使われていた = を、Swift の他の「ラベル: 値」構文と同じく : に置き換えます。ルールは「これまで属性で = を書いていた場所は、すべて : に読み替える」という一対一の素直な対応です。

// Before
@available(*, unavailable, renamed="MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol

@warn_unused_result(mutable_variant="sortInPlace")
public func sort() -> [Self.Generator.Element]

@available(*, deprecated, message="it will be removed in Swift 3.  Use the 'generate()' method on the collection.")
public init(_ bounds: Range<Element>)

// After
@available(*, unavailable, renamed: "MyRenamedProtocol")
typealias MyProtocol = MyRenamedProtocol

@warn_unused_result(mutable_variant: "sortInPlace")
public func sort() -> [Self.Generator.Element]

@available(*, deprecated, message: "it will be removed in Swift 3.  Use the 'generate()' method on the collection.")
public init(_ bounds: Range<Element>)

対象となるラベルは、当時の属性で使われていた introduced / deprecated / obsoleted / message / renamed / mutable_variant などです。いずれも書式だけの置き換えで、ラベルの名前や意味は変わりません。

この変更は Swift 3.0 で実装され、属性の引数も関数呼び出しや辞書リテラルと同じ ラベル: 値 のリズムで書けるようになりました。結果として、言語の他の部分と揃った一貫した見た目になっています。