一. reduce
高階函數(shù)reduce有兩個(gè)聲明
- 第一個(gè)參數(shù)的參數(shù)標(biāo)簽為
_
,第二個(gè)參數(shù)是一個(gè)閉包纺弊,名為nextPartialResult
,即下一個(gè)部分結(jié)果嗅剖,閉包的首參為泛型Result
- 第一個(gè)參數(shù)的參數(shù)標(biāo)簽為
@inlinable public func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
- 第一個(gè)參數(shù)的參數(shù)標(biāo)簽為
into
,第二個(gè)參數(shù)也是一個(gè)閉包衷快,名為updateAccumulatingResult
,即更新累加的結(jié)果尤揣,閉包的首參為泛型inout Result
- 第一個(gè)參數(shù)的參數(shù)標(biāo)簽為
@inlinable public func reduce<Result>(into initialResult: Result, _ updateAccumulatingResult: (inout Result, Element) throws -> ()) rethrows -> Result
- 所以搔啊,泛型Result在聲明1里面只支持
let
,而在聲明2里面支持var
, 這是他倆本質(zhì)的區(qū)別
做個(gè)測(cè)試:
- 報(bào)錯(cuò)
Cannot use mutating member on immutable value: 'partialResult' is a 'let' constant
, partialResult是個(gè)let
變量,不能進(jìn)行append
let ctrlTypes = [HomeViewController.self,
OtherViewController.self]
let ctrls = ctrlTypes.reduce([]) { partialResult, type in
let nav = BaseNavigationController(rootViewController: type.init())
return partialResult.append(nav)
}
- 使用
inout
則沒有問題
let ctrlTypes = [HomeViewController.self,
OtherViewController.self]
let ctrls = ctrlTypes.reduce(into: [UIViewController]()) { partialResult, type in
let nav = BaseNavigationController(rootViewController: type.init())
return partialResult.append(nav)
}
let intArr = [1, 2, 3]
//結(jié)果為6芹缔, 沒有問題
let ret0 = intArr.reduce(0) { partialResult, num in
partialResult + num
}
let ret1 = intArr.reduce(into: 0) { partialResult, num in
partialResult + num //結(jié)果為0坯癣,因?yàn)槌跏贾?是引用傳遞瓶盛,系統(tǒng)并不會(huì)將相加的值再賦值給partialResult
partialResult += num// 結(jié)果為6最欠,正確
}
總結(jié):
- 兩個(gè)聲明的本質(zhì)是值傳遞和引用傳遞(inout)的區(qū)別
- 兩個(gè)聲明的閉包內(nèi)部實(shí)現(xiàn)不一致。針對(duì)值傳遞惩猫,會(huì)將閉包的出參給下一個(gè)閉包的入?yún)? 針對(duì)引用傳遞芝硬,系統(tǒng)并不會(huì)幫我們做這些,需要我們自己實(shí)現(xiàn)