此代码满足您的要求。
. 也许 吧
Sourcery
protocol Unwrappable {
associatedtype T
func unwrap(_ default: T) -> T
}
extension Optional {}
extension Optional: Unwrappable where Wrapped: Unwrappable {
typealias T = Wrapped.T
func unwrap(_ defaultValue: T) -> T {
if let value = self {
return value.unwrap(defaultValue)
}
return defaultValue
}
}
extension Int: Unwrappable {
typealias T = Int
func unwrap(_ default: Int) -> Int {
return self
}
}
let nestedOptionalValue: Int??? = 6
let nestedOptionalNil: Int??? = nil
let optionalValue: Int? = 6
let optionalNil: Int? = nil
print(nestedOptionalValue.unwrap(0)) // prints 6
print(nestedOptionalNil.unwrap(0)) // prints 0
print(optionalValue.unwrap(0)) // prints 6
print(optionalNil.unwrap(0)) // prints 0
诀窍在于,Unwrappable协议标记了最终可以展开(如在0、1或更多展开之后)为特定类型的类型。
这个问题的困难在于,在Optional的扩展中,可以获得Wrapped类型,但是如果Wrapped再次是Optional,则无法访问Wrapped.Wrapped(换句话说,Swift不支持更高种类的类型)。
Optional where Wrapped == Optional
. 但是您需要更高类型的支持来访问Wrapped.Wrapped类型。如果我们试图扩展
Optional where Wrapped == Optional<T>