Swift中的Multi-Optional类型

Boh*_*ych 3 optional swift

我很好奇为什么Swift不会自动将Multi-Optional类型转换为Optional?我们假设我们有这样的代码:

var a: Int?? = 2
var b: Int? = a //error
Run Code Online (Sandbox Code Playgroud)

所有案例:

       Optional<Optional<2>>
                 /\
        .none       .some(Optional(Int))
                            /\
                       .none  .some(2)
Run Code Online (Sandbox Code Playgroud)

因此,所有的案例有:.none,.some(.none),.some(2).目前雨燕自动转换TypeOptional<Type>那么为什么不能做同样的.some(.none).none?我用扩展方法部分地解决了这个问题,但是例如4-Optional,方法应该被调用2次,这是不好的:

extension Optional {
    public func flatten<Result>() -> Result?
        where Wrapped == Result?
    {
        return self.flatMap { $0 }
    }
}
Run Code Online (Sandbox Code Playgroud)

Swe*_*per 5

我认为你想要的第一个代码片段是:

var a: Int? = 2
var b: Int?? = a
Run Code Online (Sandbox Code Playgroud)

编译没有错误.斯威夫特可以隐式转换Int?Int??,同样的方式转换IntInt?

你的片段:

var a: Int?? = 2
var b: Int? = a
Run Code Online (Sandbox Code Playgroud)

不编译,因为斯威夫特不能隐式转换Int??Int?,只是因为它不能转换Int?Int隐式.

基本上,斯威夫特可以隐包裹自选,但不能隐包装它们.

目前雨燕自动转换TypeOptional<Type>那么为什么不能做同样的.some(.none).none

你提到的两次转换是不一样的.转换TypeOptional<Type>始终有效,这在编译时是已知的.然而,从转换.some(.none).none,因为只有在运行时才能知道是否可选的是并不总是可行的.some.none,所以斯威夫特说:"不,我不知道这一点,所以我不会允许它".

换句话说,要转换.some(.none).none,您需要强制解包:

let a: Int?? = .some(nil)

if case .some(.none) = a {
    print(".some(.none) confirmed")
}

let b: Int? = a! // force unwrap here

if case .none = b {
    print(".none confirmed")
}
Run Code Online (Sandbox Code Playgroud)

否则Swift会说"如果外部选项是.none什么?" 并产生你看到的编译器错误.

编辑:

如果你想创建一个展平可选项的函数,你实际上并不需要编写这样的函数!该as?运营商已经做这件工作!

let a: Int??????? = 2
let b: Int? = a as? Int // as? unwraps every nested optional!
Run Code Online (Sandbox Code Playgroud)