一. reduce
高阶函数reduce有两个声明
- 第一个参数的参数标签为
_
,第二个参数是一个闭包,名为nextPartialResult
,即下一个部分结果,闭包的首参为泛型Result
- 第一个参数的参数标签为
@inlinable public func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
- 第一个参数的参数标签为
into
,第二个参数也是一个闭包,名为updateAccumulatingResult
,即更新累加的结果,闭包的首参为泛型inout Result
- 第一个参数的参数标签为
@inlinable public func reduce<Result>(into initialResult: Result, _ updateAccumulatingResult: (inout Result, Element) throws -> ()) rethrows -> Result
- 所以,泛型Result在声明1里面只支持
let
,而在声明2里面支持var
, 这是他俩本质的区别
做个测试:
- 报错
Cannot use mutating member on immutable value: 'partialResult' is a 'let' constant
, partialResult是个let
变量,不能进行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]
//结果为6, 没有问题
let ret0 = intArr.reduce(0) { partialResult, num in
partialResult + num
}
let ret1 = intArr.reduce(into: 0) { partialResult, num in
partialResult + num //结果为0,因为初始值0是引用传递,系统并不会将相加的值再赋值给partialResult
partialResult += num// 结果为6,正确
}
总结:
- 两个声明的本质是值传递和引用传递(inout)的区别
- 两个声明的闭包内部实现不一致。针对值传递,会将闭包的出参给下一个闭包的入参; 针对引用传递,系统并不会帮我们做这些,需要我们自己实现