値型と異なり、参照型は変数や定数に代入されるときや、関数に渡されるときにコピーされません。コピーではなく、同じインスタンスの参照になります。

次の例では、前に定義した VideoMode クラスです。

let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

この例では、新しい定数 tenEighty を宣言し、VideoMode クラスの新しいインスタンスの参照を設定しています。ビデオモードは 1920 x 1080 の HD 解像度のコピーが代入されています。インターレースに設定され、名前には "1080i" が与えられています。最後に、フレームレートが 25.0 fps に設定されています。

次に、tenEighty は新たな定数 alsoTenEighty に代入され、alsoTenEighty のフレームレートが変更されています。

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

クラスは参照型であるため、tenEighty と alsoTenEighty の両方が同じ VideoMode インスタンスを参照します。実際には、1 つの同じインスタンスに異なる名前が付いているだけです。

tenEighty の frameRate プロパティを確認すると、VideoMode インスタンスの新たなフレームレート 30.0 になっています。

print("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// "The frameRate property of tenEighty is now 30.0" と出力

tenEighty と alsoTenEighty は変数ではなく、定数として宣言されています。それにもかかわらず、tenEighty.frameRate と alsoTenEighty.frameRate を変更できるのは、定数の tenEighty と alsoTenEighty 自体の値を変更しているわけではないためです。tenEightyと alsoTenEighty は、VideoMode インスタンス自体を保持してはおらず、VideoMode インスタンスを参照しています。VideoMode を参照する定数の値が変更されているのではなく、VideoMode の frameRate プロパティが変更されているのです。

アイデンティティ演算子

クラスは参照型であるため、複数の定数や変数によって 1 つの同じクラスインスタンスを参照することができます。(構造体や列挙型では、定数や変数に代入されるときや、関数に渡されるときに常にコピーされるため、同じにはなりません。)

2 つの定数または変数が、あるクラスのまったく同じインスタンスを参照しているかどうかを調べるために役立つアイデンティティ演算子が、Swift には 2 つあります。

  • 一致 (===)
  • 不一致 (!==)

2 つの定数または変数が同じインスタンスを参照しているかどうかを確認するために、これらの演算子を使用します。

if tenEighty === alsoTenEighty {
    print("tenEighty and alsoTenEighty refer to the same VideoMode instance.")
}
// "tenEighty and alsoTenEighty refer to the same VideoMode instance." と出力

「一致」(3 つのイコール記号 ===)は、「等しい」(2 つのイコール記号 ==)と同じ意味ではありません。

  • 「一致」は、2 つのクラス型の定数または変数が、まったく同じクラスインスタンスを参照していることを意味します。
  • 「等しい」は、型の設計者によって定義された「等しい」の意味に対して、2 つのインスタンスが等しい、あるいは等価とみなせることを意味します。

独自のクラスや構造体を定義するとき、2 つのインスタンスが「等しい」ことの条件を決定する責任があります。「等しい」および「等しくない」演算子の実装を定義する方法は、Equivalence Operators で説明されています。

ポインタ

C や C++、Objective-C の経験がある場合、これらの言語ではメモリ上のアドレスを参照するためにポインタを使用することをご存知だと思います。参照型のインスタンスを参照する Swift の定数や変数は、C でのポインタに似ていますが、メモリ上のアドレスに対する直接のポインタではなく、参照であることを示すアスタリスク (*) を記述する必要はありません。そうせずに、これらの参照を Swift での他の定数や変数と同じように定義します。


Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.