Swift基礎文法

# Swift基礎文法

Swiftの初学者向けの内容です。
忘備録的な意味で基本的な構文を残しておきます。

## コメント

### 単数行

```swift
// コメント
```

### 複数行

```swift
/* コメント
コメント
ここまでコメント*/ 
```

## print文

Playgroundのデバッグエリアに文字出力する。

```swift
print("デバッグに出力") // 文字列をそのまま出力する
print(hoge) // 変数の内容を出力する
```

## 変数

再代入可能な変数を宣言・初期化する。

```swift
var hoge: Int = 0
```

宣言の型は省略できる。

```swift
var hoge = 0 
```

## 定数

イミュータブル（変更不可）な定数を扱う。
再代入しようとするとエラーになるため、意図しない代入を防げる。

```swift
let foo = "boo"
foo = "test" // 再代入すると構文エラー。
```

## データ型

代表的なデータ型。
浮動小数の演算はパフォーマンスを食うため、型の検討は慎重に。

| 型 | 扱う値 |とりうる値|
|:--|:-:|:--|
|Int|符号付き整数|※64bitまで|
|UInt|符号無し整数|※64bitまで|
|Float|小数|32bitまで|
|Double|小数|※64bitまで|
|Bool|真偽|true, またはfalse|

※64bitまで値が取れるのは `iPhone 5s以降` のみ
それ以前の環境ではInt64を指定しても32bitまでしか扱えない。

```swift
let val1: Int = 10
let val2: Float = 0.5
let val3: Double = 10.5
let val4: Bool = true
```

型を省略すると `値に適した型`で格納される。

```swift
let val1 = 10  // 整数
let val2 = 0.5 // 浮動小数
let val3 = true // 真偽
```

### 整数と浮動小数の計算

型を合わせてから計算する。

```swift
var value1 = 10
var value2 = 5.5
var sum = Double(value1) + value2 // 15.5
```
ただし、小数から整数に変換すると小数部分が `切り捨て` される。

```swift
var value1 = 10
var value2 = 5.5
var sum = value1 + Int(value2) // 15
```

### 文字列の計算

文字列同士は `+` で結合できる。

```swift
let str1 = "君の"
let str2 = "名は。"
print(str1 + str2) // 君の名は。
```

文字列以外の結合は `String` に変換してから行う。

```swift
let str1 = "秒速"
let str2 = "センチメートル"
var speed = 5
print(str1 + String(speed) + str2) // 秒速5センチメートル
```

変数の場合は `\(変数名)` 記法で文字列変換できる。
読みやすさを考慮して使おう。

```swift
var speed = 5
print("秒速\(speed)センチメートル") // 秒速5センチメートル
```

## 配列

複数の値を保持できる。

### 配列の宣言

letで宣言すると内容を後から変更できなくなる。

```swift
var array1: [Int] = [1, 3, 5, 7, 9]
let array2: [Int] = [2, 4, 6, 8, 10]
```

型は省略できる。

```swift
var array1 = [1, 3] 
```

宣言のみで初期化しない場合は `[型]()` と記す。

```swift
var array: [String] = [String]() // 空のString配列が出来る
```

型は省略できる。

```swift
var array = [String]() // 空のString配列が出来る
```

型違いの値は格納できない。
型違いの値を許容したい場合は `Any` 型で宣言する（取り出し時にダウンキャストする）。

```swift
var array1 = [0, "a"] // エラーになる
var array2: [Any] = [5, "a"]
print(array2[0]) // 5
print(array2[1]) // a
```

### 配列の利用

アクセスは 添字（要素番号）で行う。

```swift
var numbers = [1, 3, 5]
print(numbers[0]) // 1
```

値の追加は `append()`。

```swift
var numbers = [1, 3, 5]
numbers.append(7) //[1, 3, 5, 7]
```

値の削除は `remove(at: 添字)`。

```swift
var numbers = [1, 3, 5]
numbers.remove(at: 2) // [1, 3]
```

## 辞書

key-value方式で値を複数保持できる。

### 辞書の宣言

辞書を宣言する。
`let` で宣言した辞書は後から追加・変更ができない。

```swift
var scores1: [String:Int] = [String:Int]() // 空の辞書を作成する。
var scores2 = [String:Int]() // 宣言部の型は省略可能。
var scores3 = ["Test1":80, "Test2": 60] // 宣言と同時に代入することも出来る。
```

### 辞書に追加する

辞書に要素を追加する。

```swift
var scores = [String:Int]()
scores["Test1"] = 80
```

### 辞書を利用する

`変数名[key]` と記すと対応する `value` にアクセスできる。

```swift
var scores1 = ["Test1":80, "Test2": 60]
print(scores1["Test1"]) // 80
scores1["Test2"] = 50 
print(scores1["Test2"]) // 50
let scores2 = ["Test1":80, "Test2": 60]
scores2["Test2"] = 50 // 定数に再代入するとエラーになる。
```

`key` に対応する `value` が無い場合は `nil` が返る。
要素の削除は `nil` の代入で行う。

```swift
var scores = ["Test1":80, "Test2": 60]
print(socres["Test3"]) // nil
socres["Test2"] = nil
print(socres["Test2"]) // nil
```

## nilとOptional型

Swiftでは「何もない」ことを表現するために `nil` を使う。
nilを変数に格納するためには `Optional型` で宣言した変数に代入する必要がある。
Optional型の変数は `型?` 記法で宣言する。

```swift
var str1: String? = "hello" // オプショナル<String型>に文字列を代入
print(str1) // Optional("hello") が出力される。（ラップされた状態で出力される）
var str2: String? = nil
print(str2) // nil が出力される。
```

### Optional型のアンラップ

Optional型でラップされた値は `!` で取り出すことができる。
ただし、nilが代入されている変数を直接アンラップするとエラーになる。

```swift
var str1: String? = "hello"
print(str1!) // "hello"が出力される
var str2: String? = nil
print(str2!) // エラーになる
```

### if let構文でnilチェックする

Optional型の変数に `nil` と `値` のどちらが入っているか事前に知りたい場合は `if let構文` を使う。

```swift
var value: String? = "hello"
if let value = value {
  print(value) // アンラップされた "hello" が出力される
}
```
if let 構文では、上記のように元の変数名 value と同名の変数名を使うことができる。
スコープ内ではアンラップされた変数が優先して使われる。

アンラップ後の変数を使わない場合は、下記のようにif let 構文内で変数名を省略することができる。
省略する場合は `_` (アンダースコア) を用いる。

```swift
var value: String? = "hello"
if let _ = value {
  // value が nil でない場合の処理
}
```

### 【補足】型? がよく分からない

Optionalが初見だとなぜコンパイルエラーになるか分からないと思う。

```swift
var value1: Int? = 10
var value2 = value1 * value1 // コンパイルエラーになる
```

`型?` は `Optional<型>` と同義である。

```swift
var value1: Int? = 10
var value2: Optional<Int> = 10 
```

`Int?` は **nilが入るかもしれない型** ではなく、`Optional<Int>` という**Intとは別の型**。
だから最初のような操作はエラーになる。

```swift
var value1: Int? = 10
var value2 = value1 * value1 // Optionalそのままでは掛け算はできず、エラーになる
```

`!` は Optional<Int>型という箱から値を取り出す、と分かれば理解も深まると思う。

```swift
var value1: Int? = 10
var value2 = value1! * value1! // 100
```

### ! の省略

宣言時に `?` の代わりに `!` を使うと、Optionalから取り出す度に `!` を記す必要がなくなる。

```swift
var value1: Int! = 10
var value2 = value1 * value1 // 100
```

## 感想

これまで `連想配列` と呼んでたものを `辞書` という呼び名で呼ぶことにモダンっぽさを感じる。
Optional型は頻出なので是非おさえよう。