参照型と値型の違い　swift

#■値型 Structについて

コピーが変わってもコピー側に変化は起きない

``` swift
struct Person {
  var age: Int
}

var aoka = Person(age: 20)
var copyAoka = aoka

aoka.age += 1 

//コピー元は変化
print(aoka.age) //結果 21

//コピー側は変化なし　aoka.age += 1 する前にコピーしたのでもう別物と考える。
print(copyAoka) //結果 20 

```
``` swift

struct Person2 {
  var age: Int
}
//定数でインスタンス化した場合
let person2 = Person2(age: 20)
let person2.age = 40 //エラーになる。

```
structは値型なので定数で定義した場合
その後に
インスタンスプロパティに値を再代入しようとするとエラーになる。


#■参照型　classについて
コピー元が変わればコピー側も変化

``` swift
class Counter {
    var count: Int
    init(count: Int) {
        self.count = count
    }
}

let counter = Counter(count: 2)
let referenceToCounter = counter

//コピー元変化
counter.count += 1 //結果3

//コピー元が変化したのでコピー側も変化
referenceToCounter.count //結果3

```

``` swift
class Counter3 {
    var count = 0
}

//定数でインスタンス化
let counter3 = Counter3()
counter3.count = 40

```
classは参照型なので定数でインスタンス化して
後からインスタンスプロパティに再代入しても
参照型だからエラーにならない。

何故か
参照型とは別の場所のものを代理人が見て写している感覚

#■仕組み■■■■■■■■■■　下記バカ重要
■参照型
インスタンス会場みたいな物があると仮定
そこに来ているのはただの代理人
インスタンス会場で定数で固定されているのはこの代理人
インスタンスプロパティさん本人は家にいる.
家でインスタンスプロパテさんは変数状態

会場でインスタンスプロパティさんの値の変更できないかと言われるのは代理人
家にいるインスタンスプロパティさんに会場にいる代理人が電話して値変更してくださいって連絡
家にいるインスタンスプロパティさんは家では変数状態なのでOK変更しとくなって言ってる。
変更したインスタンスプロパティさんを代理人が参照(見てマネる)して
値を表している。


■値型
値型は代理人を使わず自らインスタンスプロパティさんが
インスタンス会場にきている
インスタンス会場で定数で固定されてるのは、本人のインスタンスプロパティさん。
会場でインスタンスプロパティさんに値変更してくれへんって言われても
いやここの会場定数ですもん無理やんって言ってエラーになる。

■上記を元に
何故値型はコピーしてコピー側の値が変更されてもコピー元は変わらないのか
何故参照型はコピーしてコピー側の値が変更されるとコピー元も変わるのか

理由
コピーが行われているのはインスタンス会場
コピーされるのはインスタンス会場にいる人!!!!
値型　本人がきて本人がコピーされる。
コピーされるのが本人ならそりゃコピー元とコピー側はもう別物になる。

参照型　代理人がコピーされるww
参照型のインスタンスプロパティさんは家でサボってる。こいつはコピーされてないオリジナル
コピー側Bの代理人がまた値の変更頼まれる。
家でサボってるインスタンスプロパティに連絡して値変更してもらう。
コピー元の代理人Aがインスタンスプロパティさんを見てもあー変更されてるのねOKってなる。
なのでコピー元Aから見てもコピー側Bから見ても同じものを参照する。
二人が参照してるのは家でサボってる同じオリジナルのインスタンスプロパティさんだから！！！！

とまあ言葉だけにして例えるとバカ難しいのですがもしちょっとでも
手助けになったら幸いです！！！

#■メソッドでのコピーの話
``` swift
class TestClass {
  var a = 20
}

func method (hage:TestClass) {
 hage
}

//代理人a誕生
let a = TestClass()

//コピー代理人b誕生
let b = a

//コピー代理人c誕生
method(hage:b)

```
メソッドに引数にクラスを持たせるとコピーが誕生

#■参照型　破壊的メソッド　やらないように注意！！

``` swift
class TestClass {
  var age = 20
}

//このメソッドのみで新たにコピーができる。引数にclassを指定
func method(hoge:TestClass) {
 hoge.age = 0
}

let a = TestClass()
a.age = 100
method(hoge:a)
print(a.age)
//結果:0
```
代理人A誕生
let c = TestClass()
c.age = 100で再代入
代理人Aが電話で100に変更よろしくねー！！
家のオリジナルインスタンスプロパティさんが100になる。

その後に
新たなコピー
問題児 代理人B誕生
method(hoge:c)のメソッド内で代理人Bが内密に電話0に値変更よろ
ageが0に...
家のオリジナルインスタンスプロパティさん100だったのが密かに0に

まさかメソッド内で変更してるとは...
これはバグりやすい！！分かりづらい
中で外の値を変更しない！！

#■賢い値型君
``` swift
struct TestStruct {
  var age = 30
  var name = "佐藤"
  var bloodtype = "A"
} 

func method(hage: TestStruct) {
  hage
}

let a = TestStruct()

method(hage:a)
```
となると全てコピーされる
TestStructはインスタンスプロパティ3つなのでそこまで容量は食わないが
インスタンスプロパティ自体が多い場合また
method(hage:a)が繰り返し色々使われると容量食う

その点classの参照型はコピーされても代理人一人やから容量食わん

■しかしメソッドの作り方によってはコピーが実行されないのがstruct(値型)

``` swift

struct TestStruct {
  var age = 30
  var name = "佐藤"
  var bloodtype = "A"
} 

//メソッド内でageのみを指定
func method(hage: TestStruct) {
  if hage.age > 20 {
 }
}

let a = TestStruct()

method(hage:a)

```
メソッド内で指定してるのageだけやん
ほなコピーするまでもないやん
ちょっとアクセスだけさせといたる
ってなる
なのでコピーしなくてもメソッドで確認だけさせてくれる！！


``` swift
func method(hage: TestStruct) {
    hage.name = "横井"  //エラー発生！！！！！！！！！！！！
  if hage.age > 20 {
 }
}
```
しかも内部での変更はダメでしょってエラーにしてくれるので
破壊的メソッドも発動しない。










#■データの保管等はstructを使う

API通信などUSER情報のデータを保持するのには
structを使う

■何故か　安全だから
APIの情報などを外部で変更されたら困る。
せっかくAPIで情報を取得したり
USERに情報をいれてもらったのに
勝手に変更したらそれはデタラメな情報になる。

今はこれぐらいの理解です。
理解がもっと深まれば更新していきます！