#はじめに
今回は、クラスと構造体の違いを備忘録としてまとめようと思います。
#クラスと構造体
クラスと構造体は値の受け渡し方法
によって、値型
と参照型
の2つに分けることができます。
ここでいう「型」というのはString型やInt型といったものではなくて
あるオブジェクトをどのように扱うべきかが事前に決まっている仕組み
のことを表します。
そして、この2つの最大の違いは変更をほかの変数や定数と共有するかどうか
にあります。
・値型は変更を共有しない
(例: struct, enum)
・参照型は変更を共有する
(例:class)
実は、値型は構造体だけではなく列挙型(enum)
も該当します。
#値型
インスタンスが値への参照ではなく値そのものを表す型
。
つまり、一度、代入したインスタンスは
再代入を行わない限り不変であり、その値が予測可能
というメリットがあります。
コードで動きを見てみましょう。
色をRGB型で表すColor型という構造体のインスタンスの受け渡しがどうなるのかを見ていきましょう。
まず、struct Colorを定義して3つの変数を用意します。
そして、変数aに先ほど定義したColorを代入します。
その後、変数bにaを代入してaのredの値を変更します。
struct Color {
var red: Int
var blue: Int
var green: Int
}
var a = Color(red: 255, blue: 0, green: 0) // 変数aに対して赤色を代入
var b = a // 変数bにaを代入
a.red = 0 // aのredを変更して黒色に変更する
// 結果↓
//aは黒になったが...
a.red // 0
a.blue // 0
b.green // 0
//bは赤のままである!
b.red // 255
b.blue // 0
b.green // 0
結果を見てみると、aを変更してもbに影響はありません
。
ここで分かることは、aをいくら変更してもbは影響を受けないということですね。
以上の例えから、値型は変数・定数への代入や関数への受け渡しのたびに値をコピーしている
ことが分かります。
#参照型
インスタンスが値への参照を表す型
。
値型と違って変数・定数への代入時や関数への受け渡し時にはインスタンスのコピーが発生しないので、効率的なインスタンスへの受け渡しができる
というメリットがあります。
例えとして、Int型の値をプロパティとして持つ参照型のクラスを見てみましょう。
変数aに対して定義したIntBoxクラスを代入し、変数bにaを代入します。
変数bにaを代入するという事は、aが参照しているインスタンスIntBox(value: 1)をbも参照している
という事になります。
つまり、変数aとbは同じ1つのインスタンスIntBox(value: 1)を持っている
ということになるんですね。
なので、下記のように変数aのvalueを変更すると、変数bの値も一緒に変わります。
class IntBox {
var value: Int
// 初期化
init(value: Int) {
self.value = value
}
}
var a = IntBox(value: 1) // aはIntBox(value: 1)を参照する
var b = a // bはaと同じインスタンスを参照する
// 両方とも1である
a.value // 1
b.value // 1
// a.valueに対して2を代入すると...
a.value = 2
// b.valueの値も2に変わる!
a.value // 2
b.value // 2
#値型と参照型はどう使い分ければいいのか?
じゃあ、実際に開発する際にこの2つをどうやって使い分けるのでしょうか?
私も詳しいことはよく分からないので調べてみました。
色々、調べてみると分かりやすい記事がいくつかあったので載せておきますね↓
Swiftで構造体とクラスを使い分ける方法(ポイント)
【Swift】構造体とクラスの使い分け
Swiftのクラスと構造体の使い分けについてのメモ
#おわり
間違っている部分があれば、遠慮なくコメントして下さると有り難いです。