我是swift的新手,我在理解如何使用(!)和(?)
方面遇到了一些困难据我所知,当存在变量可能为零的情况时,我们可以使用(?)。 当你100%确定该项目不是零时使用(!)。
1。工作正常 - 选择
var john:String?
john = "Is my name"
println(john!)
2。在运行时崩溃 - !不能为零 - 意味着这是正确的
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。在打开可选值
时,意外地发现了nilvar dict: [String:AnyObject] = Dictionary()
dict["name"]? = "John"
var str: String = dict["name"]! as String
如果有人可以帮我理解这些事情会很棒。谢谢!
答案 0 :(得分:8)
有一种误导性的解释,认为当!
'标记'为ivar然后100%不能nil
时。有可能。你只能这么说,你得到的价值已经解开了,所以你不需要强行再打开它 - 但它可以是nil
。
尝试这个例子:
var text: String! = "hello"
text = nil;
println(text)
它为您打印nil
。
您的应用可能崩溃的原因是您强行展开可选的nil
,是无效的操作数。
行由行:
var dict: [String:AnyObject]? = Dictionary() // from OP
您的dict
是可选,让我们看看您在这里做了什么:
dict["name"] = "John" // from OP
var str: String = dict["name"]! as String // from OP
你有一个可选 dict
并且你想以某种方式使用它,你有两种可能的方法:
dict?["name"] = "John" // optional chaining
它非常简单,如果字典不是name
,它会为键nil
分配新值,否则链会慷慨地落在运行中没有任何反应。
从这条线的角度来看:
var str: String = dict!["name"]! as String // forcibly unwrapped
如果字典或键的值为nil
(根据第一段说明:无效操作数强制解包nil
),它会在运行时崩溃,但{{1}如果字典和密钥都都是有效的对象,则为str
。
John
它就像魅力一样,如果dict!["name"] = "John" // forcibly unwrapped
存在,则会为键name
分配新值;但是如果dict
是dict
,那么这是运行时终止点(也就是崩溃),因为nil
无法强行打开(见上文)。
行由行:
nil
您的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
可选链接将会下降,此处不会为该键分配新值。
注意:关于这个概念,还有很多其他的事情和想法可以讲述。 Apple网站上的Swift Resources部分提供了原始文档。