繁体   English   中英

升级到iOS 12.2(Xcode 10.2)后,Swift 4.2中的奇数泛型和可选行为

[英]Odd Generics & Optional Behavior in Swift 4.2 after upgrading to iOS 12.2 (Xcode 10.2)

我们刚刚将Xcode更新为10.2(因此是iOS 12.2 SDK),并开始看到有关Swift GenericsOptionals行为的奇怪行为。 我们将Swift版本保持在4.2,因此没有Swift 5更新。 唯一的变化是从Xcode 10.1更新到Xcode 10.2。

这是一个示例代码,用于说明奇怪之处。 评论显示版本之间发生了哪些变化。 理想情况下,不应该有任何变化。

class Phone<T> {}

extension Phone {
    class func create(initial: T? = nil) -> Phone<T> {
        if let _ = initial { print("Regular: Unwrapping worked.") }
        return Phone()
    }
}

extension Phone where T == Void {
    class func create(initial: T? = nil) -> Phone<T> {
        if let _ = initial { print("T == Void: Unwrapping worked.") }
        return Phone()
    }
}

var phone: Phone<Int?> = Phone()
var phone2: Phone<Int?> = Phone()
var phone3: Phone<Int?> = Phone()

// unwrapping works iOS 12.1, doesn't work in 12.2
phone = Phone.create(initial: Optional(nil))

// unwrapping works iOS 12.1, doesn't work in 12.2
phone2 = Phone.create(initial: Optional<Int?>(nil))

// doesn't compile in iOS 12.1, unwrapping works in iOS 12.2
phone3 = Phone.create(initial: Optional<Int>(nil))

// doesn't compile in iOS 12.1, unwrapping doesn't work in 12.2 (uses the T == Void function)
let phone4 = Phone.create(initial: Optional(nil))

我们已经阅读了Xcode 10.2的发行说明,但没有发现Optionals或Generics的任何变化。 很难理解导致版本之间行为发生这种变化的原因。

phone2phone3表现方式特别有趣。 上面的代码示例中发生了一些奇怪的事情,所以问题是,是否有人知道在此版本中可能导致行为更改的原因是什么?

这是由于SE-0213:通过强制进行文字初始化,这意味着编译器现在将Optional(nil)视为nil as Optional 以前使用Optional(nil) ,你会得到一个包裹的 nil值,例如Int??.some(nil) ,但现在你得到的只是nil

所以对于以下内容:

let phone: Phone<Int?> = Phone.create(initial: Optional(nil))

编译器将其视为:

let phone: Phone<Int?> = Phone.create(initial: nil as Optional)

这相当于:

let phone: Phone<Int?> = Phone.create(initial: nil)

因为您已将通用参数T指定为Int? initial:参数需要一个Int?? 因此,通过传递nil你传递Int??.none ,因此解包失败。

恢复旧行为的一种方法是明确指定.init以强制编译器调用初始化器:

let phone: Phone<Int?> = Phone.create(initial: Optional.init(nil))

现在你传递一个Int??.some(nil)到参数并且解包成功。

但是我会问你为什么要首先处理双重包装的选项 - 除非绝对必要,否则我强烈建议你避免使用它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM