1. 程式人生 > 實用技巧 >Swift好用的map和flatmap

Swift好用的map和flatmap

map和flatmap

在swift中,map和flatmap在處理可選型別的操作上非常好用,下面就以map舉例

常規來說,我們來處理一個可選的Int值的時候,通常以下方式來處理

var num1: Int? = 10
var num2 = (num1 != nil) ? (num1! + 10) : nil

對於map函式來說。就可以用下面程式碼的方式:

var num1: Int? = 10
var num3 = num1.map{ $0 + 10 }  

兩者的列印結果如下:

var num1: Int? = 10
var num2 = (num1 != nil) ? (num1! + 10
) : nil var num3 = num1.map{ $0 + 10 } print(num2) print(num3) //Optional(20) //Optional(20)

從列印結果來說,兩者的效果是等價的,可以說map函式非常方便

而Swift中的map和flatmap效果基本上是等效,下面是兩者比較的程式碼

var num1: Int? = nil
var num2 = num1.map { $0 * 2 }
var num0 = num1.flatMap { $0 * 2 }
print(num2)
print(num0)
var num3: Int? = 20
var num4 = num3.map { $0
* 2 } var num5 = num3.flatMap { $0 * 2 } print(num4) print(num5)

列印結果如下:

nil
nil
Optional(40)
Optional(40)

從列印結果來說,兩個函式的列印結果是相同,也就是等價於效果是等效的

差異的地方對面下面函式的列印結果:

// 分別在函式傳入的閉包中,再加上一個可選的盒子
var num1: Int? = 10
var num2 = num1.map{ Optional.some( $0 * 2) }
var num3 = num1.flatMap{ Optional.some($0 * 2) }
print(num2)
print(num3)

列印結果如下:

Optional(Optional(20))
Optional(20)

對比可知,flatmap的輸出結果的時候,會只剩餘一個可選項的包裝層

檢視官方文件的方法註釋如下:

/// 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.
/// 此時使用map方式會返回一個不可選的值
//@inlinable public func map<U>(_ transform: (Wrapped) throws -> U) rethrows -> U?
/// 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.
/// 此時使用map方式會返回一個可選的值
//@inlinable public func flatMap<U>(_ transform: (Wrapped) throws -> U?) rethrows -> U?

對比可知,區別在於flagmap最後會對返回值進行解包,所以會導致上面列印結果的區別