Swift/iOS開発入門#3_Swiftの学習方法と基礎文法について

# 先に学習方法と基礎文法を抑えておく
次回は画面遷移について学習する、と前項で書きましたが、その前にSwiftの学習方法と基礎文法を先にやってしまいます。
普通のプログラミング（ここでいう普通は、言語としての学習方法、例えばC言語を使ってアルゴリズムを実装する、など）と違い、Xcodeを使ってアプリを開発するのでそれ専用の関数や文法がこの先たくさん出てきます。
そうなった時に、基礎的なSwiftの書き方を先に知っていた方が理解がしやすいので、あらかじめ基本的なところを抑えておきます。

Unityをやった時も、C#を先に知っておいた方がその後楽に応用へ入っていくことができたと思います。
例えば、
``OnCollisionEnter``
とかはUnity独自の関数ですが、
``public bool xx = true;``
はC#の文法です。bool型を知っていれば実装できる、、という経験があると思います。

# 学習方法について
アプリの開発を勉強する、となったときにStorybordでアプリをどんどん作っていくことは大切ですが、そればかりだと多分なかなかできるようになりません。
なぜなら、そこで書いたコードを根本的に理解しているかと聞かれたら怪しいからです。

```swift
var optInt:Int? = 1
print(optInt)
```
例えばこのコード書いた時、``?``が何者なのかがよくわからないと思います。ちなみにこのコードを実行するとエラーが出ます。じゃあそれは何故でしょう？

というように、知識がフワついたままアプリ開発を進めても結局参考書に載ってる程度で頭打ちになります。（ぶっちゃけこれはUnityでも言えるけど）

そのため、Xcodeでアプリ開発を勉強するときに心がけたいのは、

1.Swiftの基礎文法を勉強する。
2.参考書を使ってアプリを作ってみる。
3.そこで出てきたオブジェクト特有のコーディングを学ぶ。
4.この手順を繰り返す。

だと思います。
**Swiftという言語自体の学習とXcodeでのアプリ開発を1:1くらいの割合でこなしていく**ことが結構重要です。
（Swiftに慣れたらまた変わる)

じゃあどうやってSwiftを勉強するのかは、[AtCode問題集](https://atcoder.jp/contests/abs/tasks)をSwiftで解いてみたり、[これ(僕がpythonやるお子さん用に用意したもの)](https://qiita.com/asao0919/items/2a10ee5cd6ce9a6653c8)の問題部分をSwiftで解いてみたりしてください。

# Swift基礎文法
まずは入り口の入り口みたいなところだけやっていきます。僕自身も結構知識に穴があると思うので、ここで学んだら実際に[参考書(おすすめ)](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%AC%AC3%E7%89%88-Swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E7%9B%B4%E6%84%9F%E7%9A%84%E3%81%AA%E6%96%87%E6%B3%95%E3%81%A8%E5%AE%89%E5%85%A8%E6%80%A7%E3%82%92%E5%85%BC%E3%81%AD%E5%82%99%E3%81%88%E3%81%9F%E8%A8%80%E8%AA%9E-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4297112132/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=VVEC7J8WXPXL&keywords=swift&qid=1661493672&sprefix=s%2Caps%2C413&sr=8-4)とかを常に持ち歩いて電車の中とか待ち時間とかに読み漁るのがいいと思います。

それでは、実際に書きながらやっていくので、Xcodeで新しいプロジェクトを開いてみましょう。名前はpracticeとかでいいです。ViewController.swiftに書いていきます。

## 型
### 変数と定数

 Swiftには勝手に型を考えてくれる**型推論**があります。
例えば、次を実行してみてください
```Swift
import UIKit

class ViewController: UIViewController {
    var a = 10
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        //type(of: 変数名)で変数名の型を調べられる。
        print(type(of: a))
    }
}
```
コンソールエリアに``Int``と表示されると思います。
![スクリーンショット 2022-08-26 15.07.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2442087/dc79e8e3-17cd-2599-6380-67613733fe26.png)

Int型だと宣言していないのに勝手にIntだと判定してくれました。便利ですね。
このように変数宣言をすることができます。また、型を決めることも下のように書けばできます。
```swift
var x: Int
var y: String = "あいうえお"
```

定数も同じように宣言します。
```swift
let x: Int
let y: String = "かきくけこ"
```
定数・・この先のプログラムでかえることができない
変数・・この先のプログラムでかえることができる

### 範囲型
範囲を指定する型です。繰り返し文(forなど)によく使います。
```swift
let a = 1..<9//1から8まで、９は含まない
let b = 1...9//1から9まで、９を含む
```

### オプショナル型
これがSwiftの第一関門です（というか、これ以外は分かりやすくて便利だから実質一番むずい).
C#をやっている時、変数の中に値が存在しない場合は``null``という状態でした。
Swiftの普通の変数たちはこれを許してくれません。nullを使うのであれば、***オプショナル型***を使わなければいけません。

Swifitでのnullは、**nil**と表記します。

#### 変数宣言
下のように宣言します。これはオプショナルInt型です。
```swift
var optInt: Int? = 10
//または
var optInt: Optinal<Int> = 10
```
しかし、このままではオプショナル変数optIntは使えません。
なぜなら、nilかもしれないからです。

#### アンラップ
オプショナル変数optIntの中にちゃんと値があるかどうが確認して、使ってもいいよーという状態にすることを***アンラップ***と言います。これによってSwiftは安全性を高めています。
アンラップには**if-let文**を使います。実際に書いてみましょう。

```swift
import UIKit

class ViewController: UIViewController {
    var optInt: Int? = 10
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        if let x = optInt{ //optIntに値が入っていれば、それをxに代入してこのカッコに入る。
            let toZero = x-10
            print("アンラップして計算して\(toZero)になりました")
        }else{ //optIntがnilのままだったらこちら側が実行される。
            print("optIntはnilのままです。")
        }
    }
}
```
試しに``var optInt: Int? = nil``に書き換えて実行してみてください。

#### 強制アンラップ
絶対にnilではないと確信がある時のみ、**!を使うことでアンラップ**することができます。
```swift
var a:Int? = 1
let x = a! +1
print(x)//2
```

#### まとめ
* ?はオプショナル型を表している
* オプショナル型とは、nilがあるかもしれない型のこと
* そのままではオプショナル型を使うことができず、if-let文を使って中に値があるかどうか確かめてから初めて使うことができる。
* オプショナル型を使えるようにすることをアンラップするという。


## 配列
配列は次のように宣言します。
```swift
var array1: Array<Int> = [1,2,3,4]
var array2: [Int] = [1,2,3,4]
var array3 = [1,2,3,4]
```
三つ目は型推論をしてくれます。
最初から値があるなら三つ目、最初に値がないなら二つ目を使うのが簡単だと思います。

## 制御構文(if文)
if文です。超重要。
``if 要素1 演算子 要素2{}``のように書きます。
c#との大きな違いは比較演算のところに()が入らないところです.
```swift
import UIKit

class ViewController: UIViewController {
    var x = 100
    var y = 50
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        if x>y {
            print("xの方がでかい")
        }else{
            print("yのがでかい")
        }
    }
}
```
```
出力: xの方がでかい
```
となります。

## 繰り返し構文(for文)
``for 要素 in 範囲``
と書きます。
```swift
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        for i in 1...9 {
            print(i)
        }
       
    }
}
```
実行するとコンソール欄に1から9までの数字が出力されました。
while文、break,continueはc＃とほぼ一緒なので割愛します。

## 関数
関数は
``func 関数名(引数:型)->戻り値の型{return 戻り値}``
と書きます。
```swift
import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        //ここで関数を呼ぶ
        abc()
    }
    
    //関数を作成
    func abc() -> Void {
        print("call!")
    }
    
}
```
戻り値がないバージョンです。callと出力されます。

```swift
import UIKit

class ViewController: UIViewController {
    var x:Int = 0
    var y = 2
    var z = 4
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        x = cal(a: y, b: z)
        print(x)
    }
    func cal(a:Int,b:Int) -> Int {
        let result = a+b
        return result
    }
    
}
```
戻り値あるバージョンです。y+z、つまり２＋４して出力します。


この辺りが抑えられていれば、まずは初歩的なXcodeのアプリ制作で？？状態になることはあまりないと思います。
一度に全部やると疲れるので、構造体やクロージャ、クラスについてはまた追々やります。

# 練習問題
過去pythonのQiitaを書いた時のものから抜粋です。
練習だと思ってやってみてください

#### 問題1
・1日は何秒かSwiftを書いて求めてみましょう
・1,296,000秒は何日でしょうか

#### 問題2
・まずは0~9の配列を作ってみましょう
・その中で５番目のみ消してください。
・そのlistの末尾に消えてしまった数字を挿入してください。
・listの先頭に95を挿入してみましょう。
・その要素を昇順にソートしてください。ソートとは並び替えるという意味で、昇順というのはだんだん大きくなるということです。

#### 問題3
・変数を二つ用意してその数字が10より大きければ'big'、小さければ'small'と出力するプログラムを書いてみましょう。
☆ある数字を入力して、その数字が2で割り切れれば偶数、割れなければ奇数と出力するプログラムを書いてみましょう。(TextFieldを使って値を取得する必要があります。調べてやってみてください.難しかったら飛ばしておけ。後でやるので)

#### 問題4
・0から100までを出力するプログラムを書いてみましょう。
・次は、100から0に向かって、100,99,98,97,,,とカウントするプログラムを書いてみましょう。
・上のループを改造して、100から2こ飛ばしで0までカウントするプログラムを書いてみましょう。

#### 問題5
・0から100まで、2で割り切れる数のみ出力するプログラムを書きましょう。
・掛け算九九を出力してみましょう

#### 問題6
・1024を3で割った時の整数値(あまりを無視した答え)は幾つでしょうか
・12の３乗は幾つでしょうか

####  問題7
・変数aとbに数字を代入し、a×bが偶数ならOdd,奇数ならEvenと表示させてみましょう。

#### 問題8
・変数aに数字を代入し、50以上100以下であれば「True」と表示するプログラムを書いてください。
・変数aに数字を代入し、その数字が2で割り切れる数字だった時、あるいは5で割り切れる数字であった時、「true」と出力するプログラムを書いてください。
・100までのすべての素数を出力するプログラムを書いてください。(素数とは、その数自身と１でしか割れない数です。)(ヒント：1と、2,3,5,7の倍数をすべて除いた数が素数です。if文をたくさん使います。for文で1~100を数えてあげるようにします。)ヒント：エラトステネスの篩
・ある数字を入力し、その年が夏季オリンピックの年か、冬季オリンピックの年か、あるいは何もない年か出力してください。ただし、東京オリンピックは2020年にします。(ヒント、夏季オリンピックは4の倍数年です)

#### 問題9
・ex3-3でも書いた、「オリンピックの年かどうか判断するプログラム」を関数にしてみましょう。
・二つの数字を受け取り、その数字を足した数を返す関数を作ってみましょう。
・底辺の長さと高さを入力して、三角形の面積を計算する関数を作ってみましょう。
・直角三角形があります。90°の角を挟む二つの辺の長さを入力したとき、対応する斜辺の長さを計算する関数を作ってみてください。ヒント：平方根の書き方を調べてみましょう。ピタゴラスの定理。