let a: Int??? = 1let b: Int??? = nilprint(a.unwrap(0),b.unwrap(0)) // should print 1,0
我可以使用基本的通用函数获得正确的输出:
extension Optional { func unwrap<T> (_ defaultValue: T) -> T { return (self as? T) ?? defaultValue }}print(a.unwrap(0),b.unwrap(0)) // 1,0
但这并不妨碍使用与可选类型不同的类型调用函数.例如,我可以调用a.unwrap(“foo”)并打印“foo”而不是“1”,因为当然你不能转换Int ???到String.
我尝试使用Wrapped,它半正确地限制了默认值,但没有给出正确的输出:
extension Optional { func unwrap (_ defaultValue: Wrapped) -> Wrapped { return (self as? Wrapped) ?? defaultValue }}print(a.unwrap(0),b.unwrap(0)) // Optional(Optional(1)),nil
它只展开一个可选的,而不是全部三个,因为nil是Int的有效值?它不会返回默认值.
有没有办法安全地做我想要的事情?
解决方法 这段代码符合您的要求.缺点是您需要在要放入选项中的每种类型中实现Unwrappable协议.也许 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??? = 6let nestedOptionalNil: Int??? = nillet optionalValue: Int? = 6let optionalNil: Int? = nilprint(nestedOptionalValue.unwrap(0)) // prints 6print(nestedOptionalNil.unwrap(0)) // prints 0print(optionalValue.unwrap(0)) // prints 6print(optionalNil.unwrap(0)) // prints 0
诀窍在于Unwrappable协议将最终可以解包的类型(如在0,1或更多次展开后展开)标记为某种类型.
这个问题的难点在于,在Optional的扩展中,你可以获得Wrapped类型,但如果Wrapped再次是可选的,你就无法访问Wrapped.Wrapped(换句话说,Swift不支持更高的Kinded类型).
另一种方法是尝试添加一个扩展名为Optional,其中Wrapped == Optional.但是,您还需要更高的类型支持才能访问Wrapped.Wrapped类型.如果我们尝试扩展Optional Wrapped == Optional< T>,我们也会失败,因为我们不能通过T一般扩展Optional.
总结以上是内存溢出为你收集整理的swift – 解包/合并多级可选全部内容,希望文章能够帮你解决swift – 解包/合并多级可选所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)