Swiftの!やら?について

# Swiftの!(エクスクラメーションマーク)や、?(クエスチョンマーク)について
記事書くの初めてかつ、歴も入社1ヶ月とかなので、メモ用くらいの認識でお願いします。
あと見にくかったらごめん
## 【背景】
新卒研修の関係で、SwiftUIという新しめの環境ではなく、storyboardというものを勉強する為に、同期に借りたSwiftの参考書↓
![たった2日でマスターできるiPhoneアプリ開発集中講座Xcode11|Swift5|対応](https://m.media-amazon.com/images/I/51boJ4nOK+L._SX258_BO1,204,203,200_.jpg)
を読んでいると、!とか?が点在していて、よくわからんかったのでまとめます。
最新の本ではないですが、一応2023/5/19の記事です。更新する気は今のところありません。
ですが、参考にしている記事が2016年とか2019年とかのものもあったので、
情報が古い可能性ありです。

前提として、プログラムにおける**nil(NULL)というのはバグの原因になる**ことが多いらしく、
それを回避するための仕組みだそうで。
それでは
___


まず使う場面が、
1. 変数宣言する時
2. 変数を使う時

の2パターンあるみたい。

##  ?(クエスチョンマーク)
### 変数を宣言する時
#### 【結論】
変数を宣言する時に、**変数の中がnilの場合もある**としたい時に使う。
これをオプショナル型とかオプショナルって呼ぶ。
中身があっても無くてもいい。オプションだよ〜。そんな感じ。
**基本的に参照・使用する際はアンラップしないとダメ**(アンラップは後述)
```swift
var number1: Int = nil　　//← これだと「中身がnilです」と怒られる
var number2: Int?　= nil　//← これで、中身がnilのnumberという変数が宣言できる。
```
ここで、
    - Int型は数字しか入らない
    - Int？型は数字とnilを入れられる
    - **Int型とInt?型は別物**
    
という認識も持ってもらいたい。
そして、？(ハテナ)を用いてnilを使用可能にすることを、
wrapすると呼ぶらしい
(Swift君にnilだと認識されないようにする為にラップでグルグル巻きにするイメージ)
**nilがSwiftにとってあまり喜ばしくないものだということは前述した通りで↑**
* ### 変数を使う時

用いる場面が書籍の後半になるので、よく分からない人は読み飛ばしてもいいかもです。
簡単なコードが思いつかないので、、

#### 【結論】
``ramen.tukemen``の
　↑　ramenがnilだった時に、本来なら
エラー → プログラム終了
となる所を、
``ramen?.tukemen``
のように、？を付けることで、**エラーではなくnilが返ってくる**

と、プログラムの強制終了を回避する為に使う。
___
```swift
class AnyClass1{
    var inTheClass: AnyClass2?
    //~~その他諸々の処理~~
}
var anyClass = AnyClass1(△△,XX) //何かのクラスがあったとする
anyClass.inTheClass.〇〇         //そのクラス内にあるinTheClass.〇〇を使いたい
```
しかし、2行目のinTheClassは、？マークが付いているので、nilの可能性がある。
仮にnilであった場合、↓
```swift
anyClass.inTheClass.〇〇
//        ↑↑↑↑↑↑↑↑↑ここがnil
```
実行したい〇〇まで到達できない。
こういった場合にエラーでプログラムが停止するので、
それを回避する手段をSwiftが講じたみたい。

具体的には、最終行を
```swift
class AnyClass1{
    var inTheClass: AnyClass2?
    //~~その他諸々の処理~~
}
var anyClass = AnyClass1(△△,XX) //ここまではさっきと同じ
anyClass.inTheClass?.〇〇
//                 ↑ここに ? を追加
```
とすることで、
``inTheClass``がnilであるが為に、〇〇を実行できないとなった際に、
**エラーではなく、nilを返す**
といった処理ができる。


## ！(エクスクラメーションマーク)
### ・　変数を宣言する時
#### 【結論】
ほとんどは変数宣言に用いる、？マークと同じ。
変数の中身がnilでもOKとしたい時に用いる。
異なるのは**使用する時にアンラップを必要としない点**

なので、
「プログラムの構造上どうしてもnilを許容しなくてはいけないが、
使用前に必ず何かを代入するようになっている」
という場合に使える。
### ・　変数を使う時
#### 【結論】
？を用いて宣言した変数の中身がnilではないことを示す為に使う。
これをアンラップという。

```swift
var number: Int? = 10 //?を用いて宣言
print(String(number!)) //!を用いてnumberがnilではないことを示す
```
↑で``number = nil``だったらエラー吐いて止まりますので。
___
上で作成した変数を用いる際は
```swift
var number: Int = 10
print(String(number)) // Int型　→　String型 に変換してprintする
```
みたいな感じで使うと思いますが、
?　を使ってnilが使える変数を使う場合、
```swift
var number: Int? = nil
print(String(number)) //numberを、　Int型　→　String型 に変換してprintする
```
これを実行するとエラーが出ました。
`String()`の()の中にnilをぶち込んだからですね。
なら、これはどうでしょう
```swift
var number: Int? = 10
print(String(number)) //numberを、　Int型　→　String型 に変換してprintする
```
これもエラーです。`String()`の()の中に10という数値を入れたのになぜでしょうね？
小学生レベルの英語力でエラー文を読むと、
「引数の型が違う」
的なことを言われているようです。
どうやらInt?型ではダメで、Int型でないといけないようです。
そんな時に用いるのが、！です。
```swift
var number: Int? = 10
print(String(number!)) //numberを、　Int型　→　String型 に変換してprintする
//                 ↑ココに ！ を追加
```
これによって、Int?型をInt型のように使えるらしいです。
ラップでグルグル巻きにされて、nilか否か分からない状態を、
「nilではないよ〜」(Int？型じゃないよ〜)
と言っているようなものなので、
これをunwrap(アンラップ)と呼ぶんだとさ。

___
### 最後に
ここまで読んだ人、お疲れ様でした。