[Swift]パン屋で学ぶ、ClassとStructの違い🍞


Swiftを勉強してて、おそらく誰もがこう思うはず、、、『ClassとStructの違いってなんや…一緒やんけ😨』
なんならenumもなんやねんって思ってます(ふふふ

でもそんな僕でも今回ざっくりと理解出来たので書いちゃいます😎

###Swift v.5.1.3でやります


##１番の違い

まずClassとStructの1番の違いは、Classは参照、Structはコピーです。
もっと噛み砕いた言い方をすると、Classは原本です。

例えば10人程のメンバーが集まって会議をするとしましょう、Classを使って会議をする場合は原本しか使えないので、1つの用紙を使って10人の意見や結果内容を書いていきます。
原本なので上書き保存の繰り返し、、、当然中身は無茶苦茶になり大炎上です🔥😱(oh!
そんな時に役立つのがStructです！Structはコピーなので10人分の用紙を用意して意見を交わし合えます！これで炎上を避けて会議が出来ます😊(やったぜ

##パン屋の経営に置き換えてコードで実践してみましょう🍞

とある町にパン屋がありました、このパン屋さんはクロワッサンと食パンを売っていて、とても美味しいと評判でいつも大賑わいです👩‍🍳{忙しい

```swift
class ClassBakery {
    // クロワッサン
    var croissant: Int
    // 食パン
    var plainBread: Int
    
    init(croissant: Int, plainBread: Int) {
        self.croissant = croissant
        self.plainBread = plainBread
    }
}

var price = ClassBakery(croissant: 200, plainBread: 300)

// クロワッサン200円
print("クロワッサン\(price.croissant)円")
// 食パン300円
print("食パン\(price.plainBread)円")
```


そんなパン屋さんが努力の甲斐があり、ついに２号店をオープンする事になりました！新店舗オープン価格で２号店のみ半額で販売します！

```swift
// １号店
var price = ClassBakery(croissant: 200, plainBread: 300)
// ２号店
var newBakeryPrice = price
// ２号店は半額に設定
newBakeryPrice.croissant = 100
newBakeryPrice.plainBread = 150


// クロワッサン200円?
print("１号店　クロワッサン\(price.croissant)円")
// 食パン300円?
print("１号店　食パン\(price.plainBread)円")

// クロワッサン100円?
print("２号店　クロワッサン\(newBakeryPrice.croissant)円")
// 食パン150円?
print("２号店　食パン\(newBakeryPrice.plainBread)円")
```

これで１号店は通常価格、２号店は半額セールで販売ができるはずです！早速販売しましょう！🤑
<img width="857" alt="スクリーンショット 2020-01-17 5.55.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344650/b8010853-d72d-ea92-6999-503d39b41bfb.png">

ってあれ！？　１号店も半額になってしまっています！！😱
これはマズい！！このままだと大赤字になってしまいます！２号店の価格が１号店にも反映されてしまっているのでしょう、急いで価格を修正します😰
<img width="854" alt="スクリーンショット 2020-01-17 6.03.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344650/ac41271f-d614-c8d4-9011-d14595f0db15.png">

でも当然ながらそんな事したら２号店の価格が半額になりません！！！😱
お客さんは半額になってないじゃないかと大激怒！🤬Twitterで詐欺パン屋と拡散されてしまい大炎上🔥🔥🔥
もう破産待った無しです。。。😇

##Sturctを使おう！
悲しい事件でしたね😭今回の敗因はClassを使って価格の設定をしてしまっている事です。Classは原本なので、途中で価格を変更すると紐づいてる全てのデータが変わってしまいます。ゲーム風に言うと上書き保存です！
なので、このパン屋が生き残る世界線を作るにはStructを使います！早速やっていきましょう！
Structの場合はClassと違ってinitを書く必要がありません！内部で自動的にやってくれます！

```swift

struct StructBakery {
    // クロワッサン
    var croissant: Int
    // 食パン
    var plainBread: Int
}
```

そしてさっきのコードをClassBakeryからStructBakeryに変更します！

```swift
// １号店      👇ここをStructBakeryにする
var price = StructBakery(croissant: 200, plainBread: 300)
// ２号店
var newBakeryPrice = price
// ２号店は半額に設定
newBakeryPrice.croissant = 100
newBakeryPrice.plainBread = 150


// クロワッサン200円?
print("１号店　クロワッサン\(price.croissant)円")
// 食パン300円?
print("１号店　食パン\(price.plainBread)円")

// クロワッサン100円?
print("２号店　クロワッサン\(newBakeryPrice.croissant)円")
// 食パン150円?
print("２号店　食パン\(newBakeryPrice.plainBread)円")
```


これで準備完了です！販売してみましょう、結果は、、、👩‍🍳{ドキドキ

<img width="846" alt="スクリーンショット 2020-01-17 6.40.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344650/b6959868-ee79-8a4b-8644-7a77c471d60b.png">

おめでとうございます！無事に１号店は通常価格、２号店は半額で販売できました！！😆🎉
これでお客さんは怒ることもなく、Twitterも炎上せずに破産せずに済みます！👩‍🍳{よかった、よかった

これが実現できたのはStructがコピーだからです。１号店からデータを参照しているのではなく、データをコピーしているので、２号店で価格を変更しても１号店に影響は起きなかったのです！
こんな感じ👇

```swift

// １号店
var price = StructBakery(croissant: 200, plainBread: 300)
// ２号店
var newBakeryPrice = price 👈ここでコピー
// ２号店は半額に設定
newBakeryPrice.croissant = 100 👈コピーしたデータを変更
newBakeryPrice.plainBread = 150 👈コピーしたデータを変更


// クロワッサン200円?
print("１号店　クロワッサン\(price.croissant)円") 👈元のデータが反映される
// 食パン300円?
print("１号店　食パン\(price.plainBread)円") 👈元のデータが反映される

// クロワッサン100円?
print("２号店　クロワッサン\(newBakeryPrice.croissant)円") 👈コピーして変更したデータが反映される
// 食パン150円?
print("２号店　食パン\(newBakeryPrice.plainBread)円") 👈コピーして変更したデータが反映される

```

なのでClassにはSuperClassといってクラスを継承し、親クラスを作ることが出来ますが、Structはコピーなので親を作って継承することが出来ません。(コピーだから親も糞もない)

##終わり
以上がClassとStructの1番の違いでした！ざっくりとですが理解出来ましたでしょうか？
ClassとStructの違いは他にもデータの保存場所の違いなど、いろいろあるのですが、そこら辺はまだしっかり理解出来ていないので、もっと知識が固まったら細かい違いなども別記事で書いていきたいと思います！

それでは

👩‍🍳{ See you