【Swift】Appleの新言語「Swift」のリファレンスを読む(19) - Dynamic Type、Attribute、Special Literals
- (1) - The Basic
- (2) - Basic Operators、Strings and Characters
- (3) - Collection Types
- (4) - Control Flow
- (5) - Functions
- (6) - Closures、Enumerations
- (7) - Classes and Structures
- (8) - Properties
- (9) - Methods、Subscripts
- (10) - Inheritance
- (11) - Initialization
- (12) - Deinitialization、Automatic Reference Counting
- (13) - Optional Chaining
- (14) - Type Casting、Nested Types
- (15) - Extensions
- (16) - Protocols
- (17) - Generics
- (18) - Advanced Operators
- (19) - Dynamic Type、Attribute、Special Literals
注意
- あくまでメモ書きなので細かい部分を端折りますし、色々間違ってるかもしれません。ちゃんとした内容は原文を読んでね。
- コード例は基本的に原文からそのまま引用していますが、ちょっとした注釈をつけたり、統合したりしています。
SyntaxHighlighterが対応してないので微妙に読みにくいです。SyntaxHighlighterはこちらのものを使用させて頂いてます。- 他言語にそっくりな部分でも指摘しない。(自戒)
Dynamic Type
Dynamic Typeに関してはTypesと言う章のMetatype Typeと言うセクションに記述されています。
先にコード例を見てみましょう。
class SomeBaseClass { class func printClassName() { println("SomeBaseClass") } } class SomeSubClass: SomeBaseClass { override class func printClassName() { println("SomeSubClass") } } let someInstance: SomeBaseClass = SomeSubClass() // someInstance is of type SomeBaseClass at compile time, but // someInstance is of type SomeSubClass at runtime someInstance.dynamicType.printClassName() // prints "SomeSubClass"
ここでsomeInstanceはSomeBaseClassとして宣言されています。が、実体はSomeBaseClassを継承したSomeSubClassです。
someInstance.printClassNameを呼び出すとSomeBaseClassの方の静的メソッドを呼び出してしまいますが、間にdynamicTypeを挟むことによってSomeSubClassの方の静的メソッドを呼び出すことができます。
静的メソッドのオーバーライドを完全にサポートするなんて随分マニアックなところをフォローするなぁと思うんですが、最近の言語はそんなもんなんでしょうか。
Attributes
所謂「属性」とか「注釈」として扱われるあれですね。
驚いたことに、この手の機能にしては珍しくオリジナルのものを作成することはできません。ちょっと信じられないので色々調べてみたんですが、文句を言ってる人すらあんまり見かけません。まぁまだメタプログラミングとかリフレクションとか考える段階でもないっちゃないんですが、欲しくないですか?普通に。それとももっといい機能があるのかな?
気を取り直して解説していきましょう。
Attributeは何かしらの宣言時、もしくは型そのものにのみ付与することができます。自作できないのでてっきりこのドキュメントに全部載ってるのかな?と思ったら、他の章で何度か見かけたlazyとかがないので、もうなんか、これを説明する気があんまりなくなってきました…。
Declaration Attributes
assignment
演算子のオーバーロードや自作の演算子を定義するときに使います。
class_protocol
プロトコルがクラスにのみ適合可能なことを示します。クラスメソッドとかクラスプロパティが定義されてるときに使うんですかね。また、objcと言うAttributeが付与されている場合はつけなくていいそうです。
noreturn
functionやmethodに付与します。文字通り「呼ばれても何の値も返しませんよ」と言うことを示します。
これがついていてもオーバーライドは可能ですが、当然ながらオーバーライドしたものでもnoreturnである必要があります。
NSCopying
クラスのプロパティに付与します。Objective-Cのcopyと言うAttributeと似た性質を持つらしいです。
これが設定されているプロパティのsetterではプロパティ自身の値ではなく、それをコピーしたものが用いられるそうです。内部でcopyWithZoneと言うメソッドを使うからか、このAttributeが設定されるプロパティの型はNSCopyingと言うプロトコルに適合している必要があります。
NSManaged
CoreDataと呼ばれる仕組みの互換性のためにあるAttributeみたいです。「これはNSManagedObject(あるいはそれを継承したクラス)のプロパティですよ」と言うことを示すようです。
objc
Objective-Cとの相互運用を行うためのAttributeです。
クラスやプロトコルの宣言時にこれを付与すると、暗黙的にそのメンバ(プロパティとかメソッドとか)も相互運用の対象となります。
クラスの場合であれば自動で親クラスも相互運用の対象としてくれるんですが、プロトコルの場合は自分で親プロトコルにもobjcをつけないといけません。
また、引数を渡すことでObjective-C側で使用する際の別名をつけることができます。
@objc class ExampleClass { var enabled: Bool { @objc(isEnabled) get { // Return the appropriate value } } }
上記の例であれば、ExampleClass.isEnabledでenabledの値を取得できる、と言うことです。
UIApplicationMain
Objective-CにおけるAppDelegateのようなものらしいです。いや、よく知らないんですが。
要はエントリポイントの明示的な指定、ですかね。これが指定されていない場合は「main.swift」ファイルの「main」と言う関数を呼ぶそうです。
他にもInterface Builderと関連付いたIBAction、IBDesignable、IBInspectable、IBOutletと言ったAttributeがあるそうです。Attributeの自作はできないのに開発ツールのためのAttributeがあるあたり邪悪って感じですね。(プログラマ向けジョークです)
Type Attributes
auto_closure
遅延初期化のための式を自動でクロージャにしてくれます。TypesのFunction Typeと言うセクションに細かい説明が載っています。
func simpleAssert(condition: @auto_closure () -> Bool, message: String) { if !condition() { println(message) } } let testNumber = 5 simpleAssert(testNumber % 2 == 0, "testNumber isn't an even number.") // prints "testNumber isn't an even number."
中々便利そうです。この例ではあんまり意味なくね?って言うのはともかくとして。
noreturn
さっき説明したので割愛。
Special Literals
Expressionsと言う章のPrimary Expressionsと言うセクションの一番上に書いてあります。
リテラル | 型 | 値 |
---|---|---|
__FILE__ | String | ファイル名 |
__LINE__ | Int | 行番号 |
__COLUMN__ | Int | 列番号 |
__FUNCTION__ | String | 関数名 |
なんと言うかまぁ、環境変数みたいなものです。デバッグ用ですね。
__FUNCTION__で取得できる値はプロパティのgetter / setterであればプロパティ名、と言ったように、コンテキストによって変わります。
まとめ
前回の記事から一ヶ月も経ってしまいました。忙しかったと言うか…その…やめましょう、この話は。
のんびり書いていたせいでリファレンスもいつのまにか三版になってしまっています。過去の記事を修正する予定と暇は今のところないです。が、ArrayとDictionaryの揉め事は私も知っているので、そこぐらいは直すかもしれません。…一年後とかに。
第一回の前書きでも言いましたが、個人的な理由でこの言語を使うことは多分ないでしょう。
Objective-Cも一切触ったことがないし、言ってしまえばApple製品で持っているものは一つもない(嫌いとかそう言うわけではなく、縁がない)んですが、世界でこれだけのシェアを誇る端末のソフトウェア開発用に生み出された言語がどんな思想・美学を持っているかを垣間見れればそれでいいかなと思っていたので、十分でしょう。
APIにもがっつり踏み込んでいきたい気持ちは若干あるんですが、やはりそんな暇はありません。何かの間違いでSwiftによる開発をしなければならなくなったら書くかもしれませんが。