iBooks にある “The Swift Programming Language” の勉強メモ。Objective-C と C を普段書いている自分から、ちょっと馴染みがないものを特にまとめておきます。目次は こちら。
今回は、Class と Structure に関して。
Classes, Structures
Swift では クラスを作成するのに、インターフェースファイルと実装ファイルを別々にする必要はありません。また、クラスと構造体が似ているので、これから説明することは、クラスでも構造体にでも当てはまります。そのため、クラスのインスタンスは通常、オブジェクトと呼ばれますが、ドキュメントでもより一般的なワードであるインスタンスをオブジェクトの代わりに使用しています。
1. クラスと構造体の比較
クラスと構造体の似ている側面として、
- ・プロパティを持てる
- ・メソッドを持てる
- ・クラス・構造体の値にアクセスするのに subscripts syntax を使える
- ・初期状態を定義するのにイニシャライザーを定義できる
- ・デフォルトの実装の機能を拡張できる
- ・プロトコルに従うことができる
これらの共通点に加えて、クラスができることとして、
- ・継承ができる
- ・チェック、解釈するために、クラスの型をキャストできる
- ・割り当てられたリソースを解放できる (Deinitializers)
- ・リファレンスカウンターが1つ以上持てる
クラス特有の特徴の最後に関連して、構造体が渡される場合には、いつもコピーされ、リファレンスカウンターは使われない。
2. 基本シンタックス
クラスと構造体の定義、インスタンス化、プロパティへのアクセスは C や Objective-C とよく似ています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // Define struct Resolution { var width = 0 var height = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? } // Make instances let someResolution = Resolution() let someVideoMode = VideoMode() // Access properties someVideoMode.resolution.width = 1280 println("The width of someVideoMode is now \(someVideoMode.resolution.width)") // prints "The width of someVideoMode is now 1280 |
構造体は、常にプロパティの値を指定できるイニシャライザを使用できます。
1 | let vga = Resolution(width: 640, height: 480) |
3. リファレンスとコピー
この記事の概要でも軽く触れた通り、クラスはリファレンスタイプであり、構造体はバリュータイプです。つまり、クラスが渡される時には、リファレンスが渡され、構造体が渡される時には、新しいコピーを作成します。また、Enumeration もバリュータイプで渡される時には、コピーされます。
C とは違い、構造体もメソッドを持つことができるので、構造体とクラスを選ぶ際にちょっと悩みます。その一般的なガイドラインとして、下記のような場合には、構造体を選びます。
- ・構造体の主な目的は、シンプルなデータを encapsulate すること
- ・構造体のプロパティがリファレンスでなく、コピーされて使用されるのが合理的であること
- ・他のタイプから何も継承する必要がないこと
これ以外である場合には、クラスを使用すべき。実践では、ほとんどの独自にコードをバンドルする際には、クラスが使われる。