自分がSwiftのことを多めに発表しているので結構しているかと思いますが、一応改めて基本的なところと、便利だなと思うところあたりを紹介していこうかなと!(自分の復習も兼ねて)
参考図書
改訂新版Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus) | 石川 洋資, 西山 勇世 |本 | 通販 | Amazon
静的型付き言語
コンパイル時などの実行前の段階で、変数や定数の型情報を決定する言語です。
型が違うものを入れたりなどをコンパイルエラーとして検出します。だから、実行時エラーを未然に防げる!
変数・定数
変数は、再代入可能。定数は再代入不可能。
コンパイル時に、「これはvarにしないと」、「これはletでいいと思うよ」と教えてくれます!
var a: Int = 0
a = 2
let b: Int = 0
nilの許容性
これはみなさんご存知かなと思いますが一応!
nilを許容する型としない型に明確に別れています。
例えば、Int型にnilは入れられませんが、Int?型にはnilが入れられます。
let a: Int = 0
let b: Int? = nil
このInt?型はOptional型です。Int?はシンタックスシュガーです。
シンタックスシュガー(糖衣構文)
定義済みの構文を簡単に読み書きできるようにする構文。
たとえば、配列などの作成時に、[]を用いて簡単に書くことができるのもシンタックスシュガーです。
let array = Array(arrayLiteral: "a", "b")
let array_ = ["a", "b"]
アンラップ(値がnilかどうかの判断)
コードでOptional型を使うと、nilが許容できて大変便利なのですが、そのまま使うと、みんな大好き::ぬるぽ::が出る可能性があります。そこで、Optional型をWrapped型に変換して、nilじゃない保証をしてから使います。この変換の操作をアンラップと言います。
アンラップの方法を3つ紹介します。
ちなみに、Optional型のまま、プロパティなどにアクセスしようとするともちろんエラーが出ます!
Optional Binding
値があった場合は、変数または定数に値が代入され、{}内で使用することができます。if文なので、値がない場合は、{}内にはいりません。
let optionalA: Int? = 0
if let a = optionalA {
// 定数aが使用可能
}
複数個のnilのチェックもカンマで区切ることで可能です。varで変数に代入することで、値を変えることもできます。
let optionalB: Int? = 1
if var a = optionalA, let b = optionalB {
a = 2
print(a + b) // 3
}
変数aと定数bは、Int型になっているため、a = 2のところをa = nilとはできません。
条件分岐文や繰り返し文の条件で、値の有無で処理を切り替え、値が存在したらWrapped型を取り出す方法とあるので、guard文も入ると思うので、紹介します。(個人の感想です)
guardも値がある場合は、変数・定数に代入して使用可能にします。
if letとの違いは、値を代入した変数・定数の使えるスコープです。
if letは{}内だったのですが、guardは{}の後に使用可能です。
また、{}内では、スコープ外への退出が強制されます。
func method() {
let optionalA: Int? = 0
guard let a = optionalA else {
return
}
// 定数aが使用可能
}
??演算子
値がない場合のdefaultの値を指定することでアンラップします。
let optionalA: Int? = nil
let a = optionalA ?? 0 // optionalAがnilの場合、aに0が代入される
強制アンラップ⚠️
強制的にWrapped型を取り出します。もし、nilの場合、実行時エラーになります。
let optionalA: Int? = nil
let a = optionalA! // 実行時エラー
Optional Chaining
アンラップしないで、プロパティやメソッドにアクセスする方法です。
もし、nilの場合、?以降のプロパティやメソッドへのアクセスは行われません。そして、返り値はnilになります。
let optionalA: Int? = 0
let a = optionalA?.hashValue // 0
let optionalB: Int? = nil
let b = optionalB?.hashValue // nil
ちなみに、定数aもbもOptional型になる点は注意です。なので、定数aをこの後使用する場合は、Optional Bindingするのが一般的です(個人の感想です)
let optionalA: Int? = 0
if let a = optionalA?.hashValue {
// 定数aが使用可能
}
関数
関数の書き方は言語によるので、こんな感じで書くんだという感じで良いのですが、少し機能があるのでそれについて。
書き方
funcから始まり、関数名、()の中に引数名:型、->の後に返り値の型で定義できます。返り値がない場合は、->も省略できます。
func method(a: Int) -> Int {
return a
}
let a = method(a: 0) // 0
func method1(a: Int) {
}
method1()
引数名の省略
引数名の前に_をいれると、呼び出しの時に引数名が省略できます。
func method(_ a: Int,_ b: Int) -> Int {
return a + b
}
let a = method(0, 1) // 1
外部引数名
関数の内部でa、bという引数名で使用できたのですが、呼び出し側には別の名前で引数を見せたいときに使用できます。引数の前に外部引数名を書きます。
func method(a: Int,add b: Int) -> Int {
return a + b
}
let a = method(a: 0, add: 1) // 1
インアウト引数
関数の引数への再代入はできませんが、inoutを使用することでそれが可能になります。
func method(a: inout Int) {
a = 2
}
var a = 0
method(a: &a)
print(a) // 2
可変長引数
引数を任意の個数受け取りたいときに使用します。可変長引数は、配列として、関数内部で使用できます。(引数を配列にしても同じことができます)
func method(a: Int...) {
if a.count > 0 {
print(a[0]) // 0
}
}
method(a: 0, 1, 2, 3, 4)
func method_array(a: [Int]) {
if a.count > 0 {
print(a[0]) // 0
}
}
method_array(a: [0, 1, 2, 3, 4])