Swift中如何优雅地调用对象方法实现数组元素映射转换
Swift数组映射调用实例方法的写法说明
你当前使用的实现:
let documents = docs.map { $0.toModel() }
本身就是Swift中符合语法规范、可读性足够的标准写法,不存在冗余问题。
关于你设想的let documents = docs.map(\.toModel)写法,原生语法下不可行,原因如下:
- Swift 中
map支持的KeyPath简写语法,要求传入的\.<path>是KeyPath<Root, Value>类型,作用是直接取出实例对应路径的属性值。 toModel是实例方法而非属性,直接写\.toModel得到的KeyPath指向的是「方法本身的引用」,类型为KeyPath<文档类型, () -> 目标模型类型>,如果直接传入map,最终得到的会是一个存储了所有方法引用的函数数组,而非你需要的模型实例数组。
如果确实偏好更简洁的点语法风格,可以通过给Sequence添加扩展重载实现你想要的写法:
extension Sequence { func map<T>(_ method: (Element) -> () -> T) -> [T] { map { $0.method() } } }
添加上述扩展后,就可以直接使用docs.map(\.toModel)完成转换,效果和原有闭包写法完全一致。
需要说明的是,不建议为了追求代码极短强行添加这类扩展:原生不支持方法类KeyPath直接映射是刻意的语法设计,目的是明确区分「取属性值」和「执行方法调用」两种语义,你最开始写的闭包版本对所有Swift开发者来说都没有理解成本,本身就是足够优雅的实现。
内容的提问来源于stack exchange,提问作者Ben Keil
相关产品推荐
相关产品推荐

