Swift 非常重视类型安全。整个 Swift 语言的设计都考虑到了安全性。这是 Swift 的标志之一,你应该张开双臂欢迎它。它将有助于开发干净、可读的代码,并帮助防止您的应用程序崩溃。
?
Swift 中的所有选项都用符号划分。通过?
在您声明为可选的类型的名称之后设置,您实际上不是将其转换为在 之前的类型?
,而是作为可选类型。
注意:变量或类型Int
与. 它们是不能相互操作的两种不同类型。Int?
使用可选
var myString: String?
myString = "foobar"
这并不意味着您正在使用一种String
. 这意味着您正在使用一种类型String?
(String Optional,或 Optional String)。事实上,每当你试图
print(myString)
在运行时,调试控制台将打印Optional("foobar")
. “ Optional()
”部分表示该变量在运行时可能有值,也可能没有值,但恰好当前包含字符串“foobar”。Optional()
除非您执行所谓的“展开”可选值,否则此“ ”指示将保留。
展开一个可选的意味着你现在将该类型转换为非可选的。这将生成一个新类型并将驻留在该可选类型中的值分配给新的非可选类型。通过这种方式,您可以对该变量执行操作,因为编译器已保证它具有可靠的值。
有条件地展开将检查可选项中的值是否为nil
。如果不是nil
,则会有一个新创建的常量变量,该变量将被赋值并解包到非可选常量中。从那里您可以安全地使用块中的非可选项if
。
注意:你可以给你的条件解包常量与你解包的可选变量同名。
if let myString = myString {
print(myString)
// will print "foobar"
}
有条件地展开可选项是访问可选项值的最简洁方法,因为如果它包含 nil 值,则 if let 块中的所有内容都不会执行。当然,像任何 if 语句一样,您可以包含一个 else 块
if let myString = myString {
print(myString)
// will print "foobar"
}
else {
print("No value")
}
强制展开是通过使用所谓的!
("bang") 运算符来完成的。这不太安全,但仍然允许您的代码编译。但是,每当您使用 bang 运算符时,您必须 1000% 确定您的变量在强制展开之前确实包含一个实心值。
var myString: String?
myString = "foobar"
print(myString!)
以上是完全有效的 Swift 代码。它打印出myString
设置为“foobar”的值。用户会foobar
在控制台中看到打印的内容,仅此而已。但是让我们假设该值从未设置:
var myString: String?
print(myString!)
现在我们手头有不同的情况。与 Objective-C 不同,每当尝试强制解包一个可选项,并且该可选项尚未设置并且 isnil
时,当您尝试解开可选项以查看应用程序内部的内容时,将会崩溃。
使用类型转换展开。正如我们之前所说,虽然您是unwrapping
可选的,但实际上您正在强制转换为非可选类型,您也可以将非可选类型强制转换为不同的类型。例如:
var something: Any?
在我们的代码中,变量something
将被设置为某个值。也许我们正在使用泛型,或者可能有一些其他的逻辑正在发生,这会导致这种情况发生变化。所以稍后在我们的代码中,我们想要使用something
但如果它是不同的类型,仍然能够以不同的方式对待它。在这种情况下,您将需要使用as
关键字来确定:
注意:as
运算符是您在 Swift 中键入 cast 的方式。
// Conditionally
if let thing = something as? Int {
print(thing) // 0
}
// Optionally
let thing = something as? Int
print(thing) // Optional(0)
// Forcibly
let thing = something as! Int
print(thing) // 0, if no exception is raised
as
注意两个关键字之间的区别。像以前一样,当我们强制解开一个可选项时,我们使用了!
bang 运算符来执行此操作。在这里,您将做同样的事情,但不是将其转换为非可选的,而是将其转换为Int
. 并且它必须能够向下转换为Int
,否则,就像在值为nil
您的应用程序时使用 bang 运算符一样,您的应用程序将崩溃。
为了在某种类型或数学运算中使用这些变量,它们必须被解包才能这样做。
例如,在 Swift 中,只有相同类型的有效数字数据类型可以相互操作。当您使用 强制转换类型时,as!
您会强制对该变量进行向下转换,就好像您确定它属于该类型一样,因此可以安全地操作并且不会使您的应用程序崩溃。只要变量确实是您将其转换为的类型,就可以了,否则您的手会一团糟。
尽管如此,铸造 withas!
将允许您的代码编译。通过与 an 一起铸造as?
是一个不同的故事。实际上,as?
将您声明Int
为完全不同的数据类型。
现在它是Optional(0)
如果你曾经尝试过写作业,比如
1 + Optional(1) = 2
你的数学老师可能会给你一个“F”。与斯威夫特相同。除了 Swift 宁愿不编译也不愿给你评分。因为在一天结束时, optional 实际上可能是 nil。
安全第一的孩子。