mapに渡せるのはクロージャだけではない
map()
では、transform引数にクロージャを渡します。たとえばInt型の配列を文字列化する処理を考えた場合、次のように書けます。
let foo = [1,2,3,4,5,6].map{ String($0) } // ["1", "2", "3", "4", "5", "6"]
ですが、このような初期化を伴う処理は次のようにも書けます。
let bar = [1,2,3,4,5,6].map(String.init) // 同じく["1", "2", "3", "4", "5", "6"]
このinit()
はStringInterpolationConvertible
プロトコルのメソッドです。特殊なものではありません。
extension String : StringInterpolationConvertible { /// Create an instance containing `expr`'s `print` representation. : // 中略 public init(stringInterpolationSegment expr: Int) }
この書き方のポイントは、map()
の引数にラムダでなく、カッコの付いたinit()
でもなく、init
と関数自体を渡しているところです。それにより配列の要素がinit
にそのまま渡っていき、そこで返した値がmap()
の戻りになるという寸法です。
図にしてみましょう。map{ String($0) }
が前者で、map(String.init)
が後者です。
クロージャを介さず処理を渡せるので、余分な処理も減っていることが見て取れます。
もちろん、init
に限らず私たちが作成した関数も利用できます。
func f(i:Int) -> String { return String(i*2) } let foo = [1,2,3,4,5,6].map(f) // ["2", "4", "6", "8", "10", "12"]
上手に利用したいものですね。