简体   繁体   English

可选绑定评估 optional(nil) 的不良行为

[英]Unwanted behaviour with optional binding evaluating optional(nil)

After updating xCode to version 10 (and swift 4.2), I have a strange behaviour on optional bindings将 xCode 更新到版本 10(和 swift 4.2)后,我在可选绑定上有一个奇怪的行为

The code is below, and it ´s about reading json file, T is a generic type (here String )代码在下面,它是关于读取 json 文件, T是一个泛型类型(这里是String

// Are there values for configName ?
if let values = cfg[configName] as? [String: Any] {

    print("0 - values[langCode!] = ", values[langCode!] ?? "null")
    print("1 - values[langCode!] as? T = ", values[langCode!] as? T)

    // is there a value for langCode ?
    if let value = values[langCode!] as? T {
        print("2 - value to return= ", value)
        return value
    } else {
        print("3 - Do something else ")
    }
}

In xCode 9.4.1 and Swift 4.1 I have the following logs:在 xCode 9.4.1 和 Swift 4.1 中,我有以下日志:

0 - values[langCode!] =  null
1 - values[langCode!] as? T =  nil
3 - Do something else 

That is what I want, values[langCode!] is nil and the cast also return nil so the else block is executed.这就是我想要的, values[langCode!]nil并且values[langCode!]也返回nil所以else块被执行。

In xCode 10 with Swift 4.2, I have the following logs:在带有 Swift 4.2 的 xCode 10 中,我有以下日志:

0 - values[langCode!] =  null
1 - values[langCode!] as? T =  Optional(nil)
2 - value to return=  nil

Here the if let block is executed even if values[langCode!] is "null".即使 values[langCode!] 为“null”,也会执行if let块。

One difference is that with swift 4.2 values[langCode!] as? T一个区别是 swift 4.2 values[langCode!] as? T values[langCode!] as? T is an Optional(nil) and on Swift 4.1 values[langCode!] as? T values[langCode!] as? T是一个Optional(nil)并且在 Swift 4.1 values[langCode!] as? T values[langCode!] as? T is an nil . values[langCode!] as? T是一个nil

I checked the changelog for version 4.2 and I could not see something that can explain that behaviour, I also checked that no changes have been done on JSONSerialization (used to serialize the json file)我检查了4.2 版的更改日志,但我看不到可以解释该行为的内容,我还检查了 JSONSerialization(用于序列化 json 文件)没有进行任何更改

Has someone also experienced that kind of thing when switching to Swift4.2 ?有没有人在切换到 Swift4.2 时也经历过这种事情? Does someone have an explanation ?有人有解释吗? And a work around ?并解决?

In this kind of code what is the advantage to use optional binding ?在这种代码中,使用可选绑定有什么好处? would it be bad to write if (values[langCode!] != nil) {... instead of the optional binding ?if (values[langCode!] != nil) {...而不是可选绑定会不会很糟糕?

Thanks谢谢

If you have not changed the code and it behaves differently, then that is probably a bug in Swift.如果您没有更改代码并且它的行为有所不同,那么这可能是 Swift 中的一个错误。 If you can make a small test case, you should file a bug at https://bugs.swift.org .如果你可以做一个小的测试用例,你应该在https://bugs.swift.org提交一个错误。

Anyway, it sounds like in Swift 4.1, Swift deduces type T as some non- Optional type (eg Int ), and in Swift 4.2, Swift deduces T as Optional instead (eg Int? ).无论如何,听起来就像在 Swift 4.1 中,Swift 将类型T推导出为某种非Optional类型(例如Int ),而在 Swift 4.2 中,Swift 将 T 推导出为Optional (例如Int? )。 You could check by adding this statement:您可以通过添加以下语句进行检查:

print("Type T is bound to \(T.self)")

If it prints Int (or whatever) under Swift 4.1 and Optional<Int> under Swift 4.2, then that's the problem.如果它在 Swift 4.1 下打印Int (或其他),在 Swift 4.2 下打印Optional<Int> ,那么这就是问题所在。

I answer my question since the correct answer has been given in comments.我回答我的问题,因为正确的答案已在评论中给出。

The difference observed between Swift4.1 and Swift4.2 is due to an intentional change. Swift4.1 和 Swift4.2 之间观察到的差异是由于有意更改。 @Hamish explains everything in the answer is done here: stackoverflow.com/q/52446097/2976878 @Hamish 解释了答案中的所有内容都在这里完成: stackoverflow.com/q/52446097/2976878

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

相关问题 展开可选值时意外发现nil(可选绑定) - unexpectedly found nil while unwrapping an Optional value(optional binding) SwiftUI DatePicker Binding optional Date, valid nil - SwiftUI DatePicker Binding optional Date, valid nil 在Swift中nil文字与变量nil的可选绑定 - Optional binding of nil literal vs. variable that is nil in Swift 在某些情况下,为什么Swift的可选绑定会以“ nil”成功? - Why does Swift's optional binding succeed with 'nil' in certain cases? RXSwift 绑定在展开可选值时返回意外发现 nil - RXSwift Binding returns Unexpectedly found nil while unwrapping an Optional value 隐式展开时的可选绑定可选 - Optional Binding on Implicitly Unwrapped Optional defaultCalendarForNewEvents定义为可选,但是不能使用可选绑定检查其是否为nil - defaultCalendarForNewEvents is defined as optional however can't use optional binding to check if it's nil 展开可选值(可选绑定)时,总是意外发现错误nil - keep getting error unexpectedly found nil while unwrapping an Optional value(optional binding) 测试可选的nil并将nil切换为0 - Testing optional for nil and switching nil to 0 为什么没有可选(零)但只有零? - Why there is no optional(nil) but only nil?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM