swiftのソースでmapとflatMapというメソッドがよく出てくるのだが、このメソッド名からは想像できない動作をするのでメモしておく。 (メソッド名変えてくんないかな。。)
Optionalの定義を見ると次のようになっている。
public enum Optional<Wrapped> : ExpressibleByNilLiteral { case none case some(Wrapped) public init(_ some: Wrapped) public init(nilLiteral: ()) // mapメソッドはオプショナルではない値を返すクロージャを引数に取る。 // 戻り値はオプショナル。 public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U? // flatMapメソッドはオプショナルの値を返すクロージャを引数に取る。。 // 戻り値はオプショナル。 public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U? }
mapの例
let a: Int? = Int("3") let b: Int? = a.map { $0 * $0 } print(b) // Prints "Optional(9)" let c: Int? = nil let d: Int? = c.map { $0 * $0 } print(d) // Prints "nil"
flatMapの例
let a: Int? = Int("3") let b: Int? = a.flatMap { x -> Int? in let (result, overflowed) = Int.multiplyWithOverflow(x, x) return overflowed ? nil : result } print(b) // Prints "Optional(9)"
mapもflatMapもどちらも同じような動作をするが、クロージャの戻り値がnilになる場合がある時はflatMapを使い、それ以外はmapを使うという使い分けになるだろうか。