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

时间:2014-09-03 08:14:23

标签: ios string dictionary swift

我是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。在打开可选值

时,意外地发现了nil
var dict: [String:AnyObject] = Dictionary()
dict["name"]? = "John"
var str: String = dict["name"]! as String

如果有人可以帮我理解这些事情会很棒。谢谢!

1 个答案:

答案 0 :(得分:8)

有一种误导性的解释,认为当!'标记'为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)通过强制解包;

(A)

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

它非常简单,如果字典不是name,它会为键nil分配新值,否则链会慷慨地落在运行中没有任何反应。

从这条线的角度来看:

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

如果字典或键的值为nil(根据第一段说明:无效操作数强制解包nil),它会在运行时崩溃,但{{1}如果字典和密钥都是有效的对象,则为str

(B)

John

它就像魅力一样,如果dict!["name"] = "John" // forcibly unwrapped 存在,则会为键name分配新值;但是如果dictdict,那么这是运行时终止点(也就是崩溃),因为nil无法强行打开(见上文)。


#5

行由行:

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部分提供了原始文档。