为啥 Swift 隐式展开可选的“nil”?
Posted
技术标签:
【中文标题】为啥 Swift 隐式展开可选的“nil”?【英文标题】:Why is a Swift implicitly unwrapped optional `nil`?为什么 Swift 隐式展开可选的“nil”? 【发布时间】:2015-05-20 23:19:33 【问题描述】: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
。
【问题讨论】:
nil 和空数组不一样 这是因为 Apple 尚未完成所有库的转换以使用 Objective-C 可空性注释。 【参考方案1】:我的印象是
!
,隐式展开的可选指示符,保证该类型的变量不为零。
恐怕这是一个错误的印象。隐式展开的选项可以是nil
。只有没有用任何可选限定符声明的东西,?
和 !
,才能保证不是nil
。
所以:
var definitelyCouldBeNilForcedToCheck: String?
var mightBeNilButProbablyNotBECAREFUL: String!
var definitelyNotEverNil: String
隐式解包选项有两个用例:
当你绝对肯定你的价值不会是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
当你有一个庞大的 Objective-C 语料库(比如说,Cocoa 或 UIKit),你不知道什么时候返回某个指针,它是否可以是 nil
。大多数时候你认为它可能不是,让你的 API 用户不得不不断地打开东西真的很烦人,但话说回来,你不知道它可以确定 '不为零,您希望他们改为阅读文档。但他们可能会忘记,但你能做什么?最终,您将审核所有函数,然后将它们设为可选项或不可为空的值。
【讨论】:
【参考方案2】:每当您看到像这样带有!
运算符的方法签名时,您必须检查它是否有nil
。
在大多数情况下,参数将是一个隐式展开的可选参数,因为它来自一个尚未更新以解释 Objective-C 可空性注释的 Objective-C 库(Objective-C 源代码文件用来告诉Swift 参数是否应该是可选的)。
Objective-C 不支持可选项的概念。
如果这是来自 Apple 库,那么他们发布 Xcode 更新将解决这个问题并将参数更改为非可选或可选只是时间问题。 Apple 没有长期计划在其参数中保留任何隐式展开的选项。
【讨论】:
【参考方案3】:不,这个符号!
不能保证变量不为零。
swift 中的选项很棘手。
假设您有以下字符串类型的变量
var name: String?
这不是字符串。这是一个可选的字符串,这是另一回事。
但是如下:
var name: String!
是一个隐式展开的可选项,这意味着调用 name 将始终给出字符串,而不是可能为 nil 的可选字符串。
如果您希望代码在可选项为 nil 时崩溃,通常使用隐式展开的可选项。
【讨论】:
不完全是。如果将该名称放在字符串中,例如 let variable = "\(name)",则该变量将类似于 "Optional(some_value)"。 !仅表示 value 很可能不是 nil ,因此打开它应该是安全的。但是,如果代码使用 nil 值会崩溃,您总是需要检查 nil。最好尽量不要用!一点也不。采用 ?对于不能为 nil 的值的选项和无选项,所以你不会忘记检查 nil以上是关于为啥 Swift 隐式展开可选的“nil”?的主要内容,如果未能解决你的问题,请参考以下文章
在隐式展开可选值 AVAUDIO Player SWIFT 时意外发现 nil