ios - 如何在 Swift 中使用 (?) 和 (!)

标签 ios string dictionary swift

我是 swift 的新手,在理解如何使用 (!) 和 (?) 时遇到了一些困难

据我所知,当存在变量可以为 nil 的实例时,我们可以使用 (?)。 并在您 100% 确定该项目不为零时使用 (!)。

<强>1。工作正常 - 可选

var john:String?
john = "Is my name"
println(john!)

<强>2。运行时崩溃 - !不能为 nil - 表示这是正确的

var john:String?
println(john!)

<强>3。工作正常

var dict: [String:AnyObject] = Dictionary()
dict["name"] = "John"
var str: String = dict["name"]! as String <--- Taking away the (!) says it's not convertible to String

<强>4。无法运行/构建 - 对我来说它类似于 1。

var dict: [String:AnyObject]? = Dictionary() ---error says does not have a member named 'subscript'
dict["name"] = "John"
var str: String = dict["name"]! as String

<强>5。展开可选值时意外发现 nil

var dict: [String:AnyObject] = Dictionary()
dict["name"]? = "John"
var str: String = dict["name"]! as String

如果有人能帮助我理解这些事情就太好了。谢谢!

最佳答案

! ‘标记’一个 ivar 时,认为 100% 不能是 nil 是一种误导性的解释。有可能。你只能说,你得到了已经展开的值,所以你不需要再次强制展开它——但它可以是 nil

例如试试这个例子:

var text: String! = "hello"
text = nil;
println(text)

它为你打印一个nil

您的应用程序崩溃的原因是您强行解包一个 nil 的可选值,这是无效的操作数


#4

逐行:

var dict: [String:AnyObject]? = Dictionary() // from OP

你的 dict 是一个可选的,让我们看看你在这里做了什么:

dict["name"] = "John" // from OP
var str: String = dict["name"]! as String // from OP

你有一个可选 dict 并且你想以某种方式使用它,你有两种可能的方法来做到这一点:

  • (A) 通过可选链;
  • (B) 通过强制展开;

(一)

dict?["name"] = "John" // optional chaining

它非常简单,如果字典不是nil,它会为键 name 分配新值,否则链会大大下降,运行时什么也不会发生。

从这条线的角度来看:

var str: String = dict!["name"]! as String // forcibly unwrapped

如果字典或键的值为 nil,它会在运行时崩溃(根据第一段所述:无效的操作数强制展开 nil),但是 str 将是 John 如果字典和键 是有效对象。

(乙)

dict!["name"] = "John" // forcibly unwrapped

它就像一个魅力,如果 dict 存在,它会为键 name 分配新值;但是如果 dictnil,那是运行时的终止点(又名崩溃),因为 nil 不能被强行解包(见上文) .


#5

逐行:

var dict: [String:AnyObject] = Dictionary() // from OP

您的 dict 不是可选的,甚至不是 nil,但字典实际上是空的,因此其中不存在任何键,包括 name.

dict["name"]? = "John" // from OP
var str: String = dict["name"]! as String // from OP

当链中的任何元素下降时,可选链总是下降——因此不会在您的代码中分配新值,但下降会优雅地发生,因此您绕过关于分配新值的第一行,但应用程序在第二行崩溃,因为该值不存在并且您尝试强制展开它(请参阅上面关于无效操作数的信息)。

因此,如果要为不存在 键分配新值,则需要从第一行删除可选链接:

dict["name"] = "John"

如果您不想通过添加新的键/值来更改原始字典,但只想覆盖现有字典,则可选链接很有用:

dict["name"] = "John"
dict["name"]? = "Jack"

在这种情况下,新值将是 Jack,因为可选链接不会下降,因为键 name 已经存在,具有不同的值,因此它可以将被覆盖;但是:

dict["name"] = nil
dict["name"]? = "Jack"

可选链将下降,此处不会为键分配新值。


注意:关于这个概念还有很多其他的事情和想法可以讲述。原始文档可在 Apple 网站上的 Swift Resources 部分找到.

关于ios - 如何在 Swift 中使用 (?) 和 (!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25639431/

相关文章:

python - 如何创建一个函数(迭代/递归)来运行 Python 中的元组字典?

pointers - 指向 map 的指针

python - 为什么 [-1 :-1:-1] not work for reversing a string?

c - 在 C 代码中提取字符串的正则表达式(不在注释内)

ios - React-native IOS 发布方案上的 Travis 错误

ios - 当应用程序打开并且我收到推送时如何添加 uiviewcontroller?

ruby - 在 Ruby 中将字符串切成给定长度的 block 的最佳方法是什么?

python - 对字典中的嵌套键进行排序

ios - 您如何在 Storyboard 中获取 UISearchbar 的结果并在另一个视点中使用这些结果?

objective-c - 在 iOS 应用程序中获取和显示来自 Facebook 的图像