为什么Swift隐式解包可选的`nil`?

时间:2015-05-20 23:19:34

标签: swift optional

self.presentTextInputControllerWithSuggestions(nil, allowedInputMode: WKTextInputMode.Plain) { (results:[AnyObject]!) -> Void in
    // results can be nil
    if let speech = results.first as? String {
        debugPrint(speech)
    }
}

请原谅我的无知,我担心我错过了对选项的基本理解。我的印象是!,隐含地展开的可选指标,是保证该类型的变量不是零。然而,这个非常简单的Apple API很少会回复nil

这是意外错误还是Optionals规范的一部分?因为如果这是规范的一部分,我不会理解为什么首先存在可选项,而不是存在可以存在的变量或nil

3 个答案:

答案 0 :(得分:7)

  

我的印象是!,隐含的未打开的可选指标,保证该类型的变量不是零。

我害怕这是一种错误的印象。隐式解包的选项可以非常nil。只有未使用任何可选限定符声明的内容(?!)才能保证为非nil

所以:

var definitelyCouldBeNilForcedToCheck: String?
var mightBeNilButProbablyNotBECAREFUL: String!
var definitelyNotEverNil: String

隐式解包的选项有两个用例:

  1. 当您绝对肯定您的价值不会是nil时,除非在非常严格的情况下。例如,假设您有一个函数在其可用的初始化程序中执行某些处理。像这样:

    class FileHandler {
        let fileHandle: SomeFileHandleType!
    
        init?(fileName: String) {
            fileHandle = open(fileName)
            if fileHandle == nil { return nil }
        }
    
        deinit {
            if fileHandle != nil {
                fileHandle.close()
            }
        }
    
        func variousMethods() {
            // can just use fileHandle without bothering about
            // unwrapping it, because it cannot possibly be nil
            // based on how you’ve written your code
        }
    }
    
  2. 当你有一个庞大的Objective-C语料库(比方说,Cocoa或UIKit)时,你不知道什么时候返回某个指针是否可以是nil。大多数时候你认为它可能不是,而且让你的API用户不得不经常解开东西真的很烦人,但是再一次,你不知道某些它可以不要,你希望他们阅读文档。但他们可能会忘记,但你能做什么?最后,您将审核所有函数,然后将它们作为可选项或不可为空的值。

答案 1 :(得分:1)

每当您在其中看到包含!运算符的方法签名时,您必须检查nil

在大多数情况下,参数将是一个隐式解包的可选项,因为它来自一个Objective-C库,它尚未更新以考虑Objective-C可空性注释(Objective-C源代码文件用来告诉它Swift是否应该是一个可选参数。

Objective-C不支持选项的概念。

如果这是来自Apple库,那么在他们发布Xcode更新之前只需要时间问题,该更新将解决此问题,并将参数更改为非可选或可选。 Apple没有长期计划将任何隐含的未包装选项留在其参数中。

答案 2 :(得分:0)

不,此符号!不能保证变量不为零。

swift中的Optionals很棘手。

假设您有以下String类型的变量

var name: String?

这不是一个字符串。这是一个可选的字符串,这是另一回事。

然而如下:

var name: String!

是一个隐式解包的可选项,这意味着调用name将始终为字符串提供可选字符串,该字符串可能为nil。

如果您希望代码在可选项为nil时崩溃,则通常使用隐式展开的可选项。