Notice
Recent Posts
Recent Comments
Link
관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] Optional의 map, flatMap 함수 본문

iOS 응용 (swift)

[iOS - swift] Optional의 map, flatMap 함수

jake-kim 2024. 1. 16. 01:38

Optional에서의 map, flatMap 개념

  • 보통 map, flatMap은 Collection Type에서 사용하지만, Optional 내부를 보면 함수로 map, flatMap이 존재
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral {
    case none
    case some(Wrapped)
    
    @inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
    @inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
}
  • map 개념
    • Optional 타입에 nil이 아닌 값이라면, Optional을 제외한 값에다가 map 클로저 안에 있는 값을 매핑하는 의미
    /// Evaluates the given closure when this `Optional` instance is not `nil`,
    /// passing the unwrapped value as a parameter.
    ///
    /// Use the `map` method with a closure that returns a non-optional value.
    /// This example performs an arithmetic operation on an
    /// optional integer.
    ///
    ///     let possibleNumber: Int? = Int("42")
    ///     let possibleSquare = possibleNumber.map { $0 * $0 }
    ///     print(possibleSquare)
    ///     // Prints "Optional(1764)"
    ///
    ///     let noNumber: Int? = nil
    ///     let noSquare = noNumber.map { $0 * $0 }
    ///     print(noSquare)
    ///     // Prints "nil"
    ///
    /// - Parameter transform: A closure that takes the unwrapped value
    ///   of the instance.
    /// - Returns: The result of the given closure. If this instance is `nil`,
    ///   returns `nil`.
    @inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
  • flatMap 개념
    • map과 유사하지만 클로저 안의 리턴 타입이 Optional인 것
    /// Evaluates the given closure when this `Optional` instance is not `nil`,
    /// passing the unwrapped value as a parameter.
    ///
    /// Use the `flatMap` method with a closure that returns an optional value.
    /// This example performs an arithmetic operation with an optional result on
    /// an optional integer.
    ///
    ///     let possibleNumber: Int? = Int("42")
    ///     let nonOverflowingSquare = possibleNumber.flatMap { x -> Int? in
    ///         let (result, overflowed) = x.multipliedReportingOverflow(by: x)
    ///         return overflowed ? nil : result
    ///     }
    ///     print(nonOverflowingSquare)
    ///     // Prints "Optional(1764)"
    ///
    /// - Parameter transform: A closure that takes the unwrapped value
    ///   of the instance.  
    /// - Returns: The result of the given closure. If this instance is `nil`,
    ///   returns `nil`.
    @inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?
  • map과 flatMap 비교하기
    • map을 쓰고 클로저 안에서 nil을 리턴하게되면 옵셔널이 이중으로 생기는 Int?? 타입이 됨
    • flatMap을 사용하면 Int? 타입이 됨
    • -> 클로저 안에서 Optional을 리턴해주는 케이스가 있다면 flatMap을 사용하고, Optional이 필요 없다면 map을 사용할 것
let a: Int? = 1

let v1 = a.map { nonOptionalValue in
    (nonOptionalValue % 2 == 0) ? nonOptionalValue : nil
}

print(v1) // Optional(nil)
/// v1은 Int?? 타입

let v2 = a.flatMap { nonOptionalValue in
    (nonOptionalValue % 2 == 0) ? nonOptionalValue : nil
}

print(v2) // nil
/// v2는 Int? 타입

Optional에서의 map, flatMap 활용 방안

  • 특정 값이 있을때, 이 값에다가 Optional unwrap없이 특정 연산을 수행하고 싶은 경우, map, flatMap을 활용할 것
    • Optional unwrap없이 사용가능하다는 것이 핵심
Comments