NOTE 昔から_オブジェクト_はクラスのインスタンスはとして知られています。ただし、 Swift の 構造体とクラスは、他の言語以上に機能がかなり似ていて、この章でも、構造体またはクラス型のインスタンスのどちらにも当てはまる機能について説明しています。このため、より一般的な意味合いでインスタンスという用語を使用します。
extension
で機能を拡張できますstruct
キーワードを使用して構造体を作成し、class
キーワードを使用してクラスを作成します。どちらも、定義全体を中括弧のペア({}
)内に配置します:NOTE 新しい構造体またはクラスを定義するときはいつでも、新しい Swift の型を定義します。標準の Swift の型(String
、Int
、Bool
など)と同じように、型にUpperCamelCase
名(ここではSomeStructure
やSomeClass
など)にします。プロパティとメソッドはlowerCamelCase
名(frameRate
やincrementCount
など)として、型名と区別します。
Resolution
と呼ばれる新しい構造体を定義して、ピクセルベースのディスプレイ解像度を記述しています。この構造体には、width
と height
という 2 つの_格納プロパティ_があります。格納プロパティは、構造体またはクラスの一部として紐付け、格納される定数または変数です。これらの 2 つのプロパティは、初期値に 0
を設定することにより、Int
型だと推論されます。VideoMode
と呼ばれる新しいクラスも定義しています。このクラスには、4 つの格納プロパティの変数があります。最初の resolution
は、新しい Resolution
構造体インスタンスで初期化されており Resolution
型だと推論されます。他の 3 つのプロパティに関しては、interlaced
に (「非インターレースビデオ」を意味する)false
を、再生フレームレートに 0.0
、および name
と呼ばれるオプショナルの String
値で初期化されます。name
プロパティはオプショナル型のため、デフォルトで nil
が自動的に設定されます。Resolution
構造体の定義と VideoMode
クラスの定義は、Resolution
または VideoMode
がどのようなものかを説明しているだけです。それら自体は、特定の解像度やビデオモードについては説明していません。そうするためには、構造体またはクラスのインスタンスを作成する必要があります。init
)を使用します。初期化構文の最もシンプルな形式では、クラスまたは構造体の型名の後に、Resolution()
や VideoMode()
などの空の括弧(()
)が続きます。これにより、クラスまたは構造の新しいインスタンスが作成され、プロパティはデフォルト値で初期化されます。クラスと構造体の初期化については、Initialization(初期化)で詳しく説明しています。.
)で区切ってプロパティ名を記述します。someResolution.width
は someResolution
の width
プロパティを参照し、デフォルトの初期値 0
を返します。VideoMode
の resolution
プロパティの width
プロパティなど、より深い階層へもアクセスできます。NOTE 配列、辞書、文字列などの標準ライブラリによって定義されたコレクションは、コピーのパフォーマンスコストを削減するように最適化されています。これらのコレクションは、すぐにコピーを作成する代わりに、元のインスタンスとコピーの間で要素が格納されているメモリを共有します。コレクションのコピーの1つが変更された場合、要素は変更の直前にコピーされます。動作上では、常にコピーがすぐに行われているかのように見えます。
Resolution
構造体を使用した場合について考えてみます。hd
という定数を宣言し、フル HD ビデオの幅と高さ(幅 1920 ピクセル、高さ 1080 ピクセル)で初期化された Resolution
インスタンスを設定します。cinema
という変数を宣言し、hd
の現在の値を設定します。Resolution
は構造体のため、既存のインスタンスのコピーが作成され、この新しいコピーが cinema
に割り当てられます。hd
と cinema
の幅と高さは同じになりましたが、内部ではまったく異なる 2 つのインスタンスです。cinema
の width
プロパティは、デジタルシネマ映写に使用される、わずかに幅の広い 2K 標準の幅(幅 2048 ピクセル、高さ 1080 ピクセル)に修正されます。cinema
の width
プロパティを確認すると、実際に 2048 に変更されていることがわかります。hd
インスタンスの width
プロパティは、1920 のままです。cinema
に hd
の現在の値が与えられると、hd
に保存されている値が新しい cinema
インスタンスにコピーされます。これらは、同じ数値を含む 2 つの完全に別個のインスタンスですが、次の図に示すように、cinema
の幅を 2048
に設定しても、hd
に保存される幅には影響しません:RememberedDirection
に currentDirection
の値が割り当てられると、実際にはその値のコピーが設定されます。その後、currentDirection
の値を変更しても、rememberedDirection
に保存されていた元の値には影響しません。VideoMode
クラスを使用した例を次に示します。tenEighty
という新しい定数を宣言し、VideoMode
クラスの新しいインスタンスを参照するように設定します。ビデオモードには、元々 1920
x 1080
の HD 解像度のコピーが割り当てられています。インターレースされるように設定され、名前には "1080i"
、フレームレートは 25.0
フレーム/秒が設定されています。tenEighty
を alsoTenEighty
という新しい定数に割り当て、alsoTenEighty
のフレームレートを変更しています。tenEighty
と alsoTenEighty
は両方とも同じ VideoMode
インスタンスを参照しています。事実上、次の図に示すように、これらは同じインスタンスに 2 つの異なる名前を付けているだけです:tenEighty
の frameRate
プロパティを確認すると、基になる VideoMode
インスタンスから 30.0
の新しいフレームレートが正しく設定されていることがわかります。tenEighty
と alsoTenEighty
がコード内で大きく離れている場合、ビデオモードが変更される全ての場所を見つけるのは難しいかもしれません。tenEighty
を使用する場合は常に alsoTenEighty
を使用するコードも考慮する必要があります。その逆も同様です。対照的に、値型は、同じ値に作用する全てのコードは近くにあるため、考慮する点が少なく扱いが簡単です。tenEighty
と alsoTenEighty
は、変数ではなく定数として宣言されていることに注目してください。それでも、tenEighty
および alsoTenEighty
定数自体の値は実際には変更されないため、tenEighty.frameRate
および alsoTenEighty.frameRate
を変更することはできます。tenEighty
と alsoTenEighty
自体は、VideoMode
インスタンスを「格納」しません。代わりに、どちらも内部で同じ VideoMode
インスタンスを参照します。変更されるのは、基になる VideoMode
の frameRate
プロパティで、その VideoMode
への参照を持つ定数ではありません。===
)!==
)===
)は、「等しい」(2 つの等号または ==
で表される)と同じではないことに注意してください。「同一」とは、クラスタイプの 2 つの定数または変数がまったく同じクラスインスタンスを参照することを意味します。「等しい」とは、型の設計者が定義する「等しい」という観点で、適切に 2 つのインスタンスの値が等しいまたは同等だと見なされることを意味します。==
および !=
演算子の独自の実装を定義するプロセスは、Equivalence Operators(等価演算子)で説明されています。*
)を記述する必要はありません。代わりに、これらの参照は、Swift の他の定数または変数と同様に定義されます。標準ライブラリには、ポインタを直接操作する必要がある場合に使用できるポインタとバッファ型が用意されています。Manual Memory Managementを参照ください。