- 100 Days of SwiftUI - Day 12 Opt
- 100 Days of SwiftUI —— Day 12:可选
- 100 Days of SwiftUI —— Day 100:期
- 100 Days of SwiftUI —— Day 65:In
- 100 Days of SwiftUI —— Day 67:In
- 100 Days of SwiftUI —— Day 66:In
- 100 Days of SwiftUI —— Day 63:In
- 100 Days of SwiftUI —— Day 62:In
- 100 Days of SwiftUI —— Day 64:In
- 100 Days of SwiftUI —— Day 3
为了解决空引用的问题,Swift使用Optionals解决方案。
1.处理丢失的数据
我们使用Int类型的age属性来保存用户的年龄,但有时候我们不知道用户的年龄,该怎么办?
存储为0,或者-1表示未知,这两个数字都是不太可能的。
Swift的解决方案是Optionals,使类型变为可选。
var age: Int? = nil
age = 38
如果我们知道年龄,可以使用它。
为什么Swift有可选类型?
在Swift中任何数据类型都可以是可选的。
2.解包 if let
展开可选内容的一种常见方法是使用if let语法
if let unwrapped = name {
print("\(unwrapped.count) letters")
} else {
print("Missing name.")
}
可选值最重要的功能之一,Swift不允许我们在不先展开它们的情况下使用它们。
这为我们所有的应用程序提供了极大的保护,因为它阻止了不确定性:当您处理一个字符串时,您知道它是有效的字符串,当您调用一个返回整数的函数时,就可以立即安全地进行操作。而且,当您的代码中确实包含可选内容时,Swift会始终确保正确处理它们-您检查并解开它们,而不仅仅是将不安全的值与已知的安全数据混合。
3.guard let
func greet(_ name: String?) {
guard let unwrapped = name else {
print("You didn't provide a name!")
return
}
print("Hello, \(unwrapped)!")
}
使用guard let, 可以在功能开始前处理问题,然后立即退出。意味着函数的其余部分是正确的,代码将采用。
使用guard let 还是 if let?
guard在方法开始时,会使用一次或多次,它用于验证条件是否正确。如果想拆开可选类型,请使用if let ,如果想检查条件,可以使用guard let。
4.强制解包
当你可以确定值不是nil时,你可以将可选类型转为非可选类型。
let str = "5"
let num = Int(str)!
这时是确定不为空的,但如果你错了,代码将崩溃。
因此只有确定它是安全时,才可以使用强制解包。
什么时候采用强制解包?
即使您99.999%确信它是安全的,也不应使用它
5.隐式解包
与常规的可选类型不同,使用时你不需要解包。
let age: Int! = nil
使用它们不需要 if let
或 guard let
当它们没有值时,使用它代码会崩溃。
使用隐式解包主要是UIKit框架中使用,布局中不会立即创建控件,延迟到用户显示时。
而在SwiftUI中,这样的方式已经消失了,隐式解包不再重要。
6.nil合并运算符
解包可选值,如果有则返回内部值,如果没有值,则使用默认值。
let user = username(for: 15) ?? "Anonymous"
7.可选链
let surnameLetter = names["Vincent"]?.first?.uppercased() ?? "?"
8.try?
do try catch
enum PasswordError: Error {
case obvious
}
func checkPassword(_ password: String) throws -> Bool {
if password == "password" {
throw PasswordError.obvious
}
return true
}
do {
try checkPassword("password")
print("That password is good!")
} catch {
print("You can't use that password.")
}
使用try?
来代替try
if let result = try? checkPassword("password") {
print("Result was \(result)")
} else {
print("D'oh.")
}
使用try!
如果可以确保函数不会失败可以使用try!
try! checkPassword("sekrit")
print("OK!")
什么时候使用try?
如果只关注函数成功或失败,使用try?是很好的选择。
9.init?()
struct Person {
var id: String
init?(id: String) {
if id.count == 9 {
self.id = id
} else {
return nil
}
}
}
初始化方法失败时,对象创建失败。你也可以将验证放到一个单独的方法中,但是你很可能忘记调用它,放入初始化程序中安全的多。
10. as?
当你知道某些对象的类型时,你可以对其进行类型转换,使用as?,转换失败时返回nil。
let pets = [Fish(), Dog(), Fish(), Dog()]
for pet in pets {
if let dog = pet as? Dog {
dog.makeNoise()
}
}
11.总结
1.可选类型使我们以清晰明确的方式表示值的缺失。
2.Swift不允许我们使用未解包的可选类型,你可以使用if let
或 guard let
解包
3.你可以强制解包,但是如果值为nil时,会崩溃。
4.隐式解包类型不会像可选类型一样检查安全。
5.nil合并运算来解包可选值,没有则使用默认值。
6.可选链使我们可以编写代码操作可选类型,如果结果为空,代码忽略。
7.使用try?会将throwing函数转换为可选的返回值。或者使用try!,注意崩溃。
8.如果在初始化时加入错误检查,可以使用init?()。
9.使用类型转换将一种类型转换为另一种类型。
网友评论