作为Swift中的一个练习,我正在尝试编写一个扩展方法,它将解包任意深度嵌套的选项.这几乎没有实际用途,只是对Swift类型系统的探索.
任意深度嵌套的选项的例子是Optional<Optional<Optional<Int>>>和Optional<Optional<Optional<Optional<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
}
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用.我们可以打开一个深层嵌套的可选项,但不幸的是我们必须重新设置Wrapped类型:
let x = Optional<Optional<Optional<Int>>>(3)
let y = x.unwrap(Int.self)
Run Code Online (Sandbox Code Playgroud)
没有类型擦除,我想不出任何方法可以做到这一点.一旦你使用了类型擦除,你必须重新设置类型才能恢复它.我不想要这个.有更多精通斯威夫特的人可以让我知道这不可能做到或者是否有另一种方式?
这是一个提供高达六级扁平化的解决方案Optional:
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
}
}
Run Code Online (Sandbox Code Playgroud)
上述解决方案的优点是类型安全,缺点是它是静态类型的(例如不能调用flatten()变量Any),并且如果需要支持更多和更多,则需要添加越来越多的重载更多嵌套级别。
| 归档时间: |
|
| 查看次数: |
374 次 |
| 最近记录: |