社畜系WEBエンジニアの消耗戦

社畜系WEBエンジニアの消耗戦

修羅の国でせっせと働く社畜系WEBエンジニアのブログ

【詳細!Swift3】Swiftの基本構文を学ぶ part3

今回は関数、クロージャまわり。この辺からようやくSwift特有のモノがガンガン出てきそうな感じがあります。あーやだやだ。全部ReactNativeで書けばいいとに。

関数を作る

引数に1を足す関数を作ってみます。

func plusOne(num: Int) -> Int {
    return num + 1
}

for i in 0..<5 {
    print(plusOne(i))
}

// 1
// 2
// 3
// 4
// 5

(引数名: 型)で引数を定義して、-> 戻り値型returnの型を定義しています。

戻り値がない場合

戻り値がない場合は上述の戻り値の部分を省略する、もしくはVoid、もしくは()のどれかを使います。

func hoge() {
    print("hoge")
}

func fuga() -> Void {
    print("fuga")
}

func piyo() -> () {
    print("piyo")
}

guard-else

条件を満たさない時に実行するもの。ちょっと使いドコロが(ry

defer

関数内に記述することで、必ず実行されるブロックを記述します。関数終了時のコールバックですね。

引数の個数を指定しない関数

例えば渡した関数を全部足して返してくれる関数を作りたくなることってないですか?まぁないですね。それはいいとして、Swiftでは引数の個数が不定の関数を作ることができます。値は配列として格納されます。こんな感じ。

func sumAll(num:Int...) -> Int {
    var total = 0
    for v in num {
        total += v
    }
    return total
}

sumAll(1,2,3,4,5)

オーバーロード

Swiftでは、同名の関数でも「引数名」「引数の数」が違うと、別の関数として定義することができます。これをオーバーロードといいます。僕がこれまで書いてきたPHPRubyなんかではないやり方ですね。

func sum(a:Int, b:Int) -> Int {
    return a + b
}

func sum(a:Int, b:Int, c:Int) -> Int {
    return a + b + c
}

ジェネリクス

引数の型によって動的に型を指定する方法です。例えば、Swiftは型が厳格なので、「引数を足す」関数でも、引数の型、戻り値の型が必要です。つまり、Intで定義した関数だとIntしか計算できないし、Floatで定義した関数ならFloatしか計算できないことになります。これは非効率ですよね。なので、<T>のような型パラメータを使って、動的に型推論をさせる関数を作ることができます。

func res<T>(a:T) -> T {
    return a
}

res(1)
res("hello")

とはいうものの、上記の例で上げた足し算だとキャストしないとコンパイルエラーになることが判明。なので使い方はまだ良くわかっていない(ry

と、とりあえずジェネリクス関数で型を動的に指定できるということだけは覚えた。

クロージャ

無名関数。よくあるやつ。

let myFunc = {(a:Int, b:Int) -> Int in
    return a + b
}
print(myFunc(1,2))

{}でくくってinをつける、と覚えれば良さそうですね。

例えば、map()関数を使えば、配列の値にすべて1を足したものを返す、とかもシンプルに記述できます。

let numArray = [1,2,3]
let addArray = numArray.map({(num:Int) -> Int in
        return num + 1
    })
print(addArray)

さらに型推論を利用して1行ステートメントにすればこう、

let addArray = numArray.map{v in v + 1}

また、クロージャの引数は$0、$1、$2で順に参照できるので、こういう書き方もできる。うーんシンプル。

let addArray = numArray.map{$0 + 1}

おわりに

今回の内容はようやくSwiftっぽさがちょっと出てきましたね。クロージャはやっぱり結構使い勝手がいいかも。でも別でちゃんと定義したほうが見通しはいいような気がしなくもない、、のは気のせいだろうか。