如何在Swift中打开任意深度嵌套的选项?
发布时间:2020-12-14 05:01:11 所属栏目:百科 来源:网络整理
导读:作为 Swift中的一个练习,我正在尝试编写一个扩展方法,它将解包任意深度嵌套的选项.这几乎没有实际用途,只是对Swift类型系统的探索. 任意深度嵌套的选项的示例是Optional Optional Optional Int和可选可选可选可选 Int. 我发现这样做的唯一方法是使用类型擦除
作为
Swift中的一个练习,我正在尝试编写一个扩展方法,它将解包任意深度嵌套的选项.这几乎没有实际用途,只是对Swift类型系统的探索.
任意深度嵌套的选项的示例是Optional< Optional< Optional< Int>>>和可选<可选<可选<可选< Int>>>>. 我发现这样做的唯一方法是使用类型擦除: protocol TypeErasedOptional { func deeplyUnwrap() -> Any? } extension Optional: TypeErasedOptional { func deeplyUnwrap() -> Any? { switch self { case .none: return nil case .some(let wrapped as TypeErasedOptional): return wrapped.deeplyUnwrap() case .some(let wrapped): return wrapped } } func unwrap<T>(_ type: T.Type = T.self) -> T? { switch deeplyUnwrap() { case .none: return nil case .some(let wrapped as T): return wrapped default: return nil } } } 这很好用.我们可以打开一个深层嵌套的可选项,但遗憾的是我们必须重新编写Wrapped类型: let x = Optional<Optional<Optional<Int>>>(3) let y = x.unwrap(Int.self) 没有类型擦除,我想不出任何方法可以做到这一点.一旦你使用了类型擦除,你必须重新设置类型才能恢复它.我不想要这个.有更多精通斯威夫特的人可??以让我知道这不可能做到或者是否有另一种方式? 解决方法
这是一个解决方案,提供最多六个级别的展平选项:
extension Optional { func flatten() -> Wrapped? { return self } func flatten<T>() -> T? where Wrapped == T? { return map { $0.flatten() } ?? nil } func flatten<T>() -> T? where Wrapped == T?? { return map { $0.flatten() } ?? nil } func flatten<T>() -> T? where Wrapped == T??? { return map { $0.flatten() } ?? nil } func flatten<T>() -> T? where Wrapped == T???? { return map { $0.flatten() } ?? nil } func flatten<T>() -> T? where Wrapped == T????? { return map { $0.flatten() } ?? nil } } 上述解决方案的优点是类型安全的事实,缺点是它是静态类型的(例如,不能在任何变量上调用flatten()),并且如果需要,您需要添加越来越多的重载支持越来越多的嵌套级别. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- ruby-on-rails – 基于对象类的控制流/条件基础设计是不是很
- React-Native学习笔记之:实现简单地登录页面
- ruby – 使用SequenceFile进行Hadoop流式处理(在AWS上)
- Nosql Mongodb之旅(30)—MongoDB移除Shard Server
- 提高Oracle DELETE性能的策略
- Flex分析 – 什么是[enterFrameEvent]在做什么?
- ruby-on-rails – 有没有办法让一个Rails 3.x应用程序使用两
- LeetCode: Regular Expression Matching——DP解决正则匹配
- pull解析细节
- AVM2_OPCODES