クロージャとコールバック関数について
Firebaseのユーザー登録のソースコードを読んでいて思った事がある。
それがここ。
Auth.auth().createUser(withEmail: email, password: password) { (res, err) in
if let err = err {
print("Auth情報の保存に失敗しました。\(err)")
return
}
まさにここで使われている構文の書き方がクロージャとコールバック関数を使っている。
つまり、この構文を理解するにはその2つを知る必要がある。
クロージャとは
クロージャとは一言で言えば変数や処理を一つの{}で囲んだまとまり
クロージャの基本構文
{(引数名1: 型, 引数名2: 型...) -> 戻り値の型 in
クロージャの実行時に実行される文
必要に応じてreturn文で戻り値を返却する
}
クロージャを実際に使ったプログラム
let double = { (x: Int) -> Int in
x * 2
}
double(2)
//実行結果
4
クロージャは変数に入れることもできる。変数に入れられるのならそれを関数の引数にも渡すことも可能。
入れなくても直がきで渡せるけど。
こんな感じ
import UIKit
//乗算関数
let multi = {(x:Int,y:Int) -> (Int) in
return x*y
}
//出力関数
func test(multifunc:(Int,Int) -> Int, b:Int, c:Int){
let result = multifunc(b,c)
print(result)
}
test(multifunc: multi,b: 5,c: 3)
//実行結果
15
コードを見ると
test関数の引数としてmulti変数(中身はクロージャ)が渡されている。
このような感じで関数を渡す事ができる。
コールバック関数とは
コールバック関数とは一言で言えば
関数の呼び出し先から、呼び出しもとの関数を呼び出すこと(ややこしい)
これはコードを見ればすぐに理解できるはず。
import UIKit
func test(x:Int,y:Int,callback:(String,Bool) ->()){
if(x+y > 10){
callback("二つの数字を足した結果は5より大きいです",true)
}else{
callback("二つの数字を足した結果は5より小さいため処理を中断します。",false)
return
}
print("最後まで処理が実行されました。")
}
test(x:4,y:6){(result,flag) in
if(flag){
print(result)
}else{
print(result)
}
return
}
これはコールバック関数で10未満の数字が入力されると処理が中断される。
実際この程度のプログラムならコールバック関数など描かなくてもいい、、、
じゃあどういった時に使うのかというと、ユーザーの認証情報を登録するときに
パスワードは何桁以上と言う制約を儲けたときに、登録情報にエラーが発生したとして
コールバック関数にエラー情報をのせて呼び出しもとに処理を移行させるとおいう使い方がある。
それがFirebaseで使われる。
createuser関数であり、エラーが発生すればその情報を取り扱う事ができるし、エラーではなく登録に成功すればresultと言う引数を受け取る事ができる。
以下がシンプル化したコールバック関数の認証情報登録のコード
//登録ユーザー情報
let name = "Matchan"
let password = "aiuio"
test(name: name, password: password){(err,res) in
if let err = err {
print(err)
return
}
//オプショナル型のnilチェック
guard let result = res else {
return
}
print(result)
//登録が成功した後の処理を書く
}
//クロージャとコールバック関数を使った関数test
func test(name: String, password: String, callback:(String?,String?) -> ()){
if(password.count<7){
callback("パスワードが6文字以下のためセキュリティ上登録できません",nil)
return
}else
{
callback(nil, "認証情報の登録が成功しました")
}
}
認証情報にエラーがあれば、
if let err = err {
print(err)
return
}
エラー出力されて処理が中断される、処理が成功ならその後の処理が継続して行われる。