这是我参与更文挑战的第3天,活动详情查看: 更文挑战
Optionals
- 可选项,通常也叫可选类型,它容许将值设置为nil
- 在类型名称后面加个问号? 来定义一个可选项
var age: Int? = nil
age = 38
复制代码
age
刚开始不表示任何数字,因为你创建一个Person
对象,一开始就知道他的年龄;只有后续赋值给他,才能知道他的值
可选项拆包
可选项有可能含有某一个值,有可能啥也没有
var name: String? = nil
复制代码
当我们使用name.count
,真实的string
是有count
数值返回的;但是当nil
,访问的是空内存,此时是没有count
方法的, 着时候Swift是不容许这么调用的
- 使用 if let 语法 拆包
if let unwrapped = name {
print("\(unwrapped.count) letters")
} else {
print("Missing name.")
}
复制代码
- if let 的替代方法 guard let
func greet(_ name: String?) {
guard let unwrapped = name else {
print("You didn't provide a name!")
return
}
print("Hello, \(unwrapped)!")
}
复制代码
**guard let**
在函数最开始的时候就 把问题给拦截了,后面就可以开心的调用了
强制拆包 “ !“
let str = "5"
let num = Int(str)
复制代码
如果str
是一个可选项值,swift
会有两种方式让我们选择,要么给str 提供一个默认值 ??
;
还有一种就是强制拆包语法“ Int(str)!”
,这表达是str 肯定能转化成int,但是如果转化不成,则会发生crash
因此,一般只有在你确定安全的情况下才使用这个语法;
可选链语法
Swift 的可选链式调用和 Objective-C 中向
nil
发送消息有些相像,但是 Swift 的可选链式调用可以应用于任意类型,并且能检查调用是否成功。
假如我们访问某个方法,比如: a.b,c
, 如果b是可选的;那么可以写成 a.b?.c
; 代码运行的时候,swift会检查b的值
如果存在则会调用c,如果返回nil,则c就不会执行了
可选Try
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.")
}
复制代码
do
, try
, catch
正常处理了异常的情况
还有一种方法可以使用 try?
if let result = try? checkPassword("password") {
print("Result was \(result)")
} else {
print("D'oh.")
}
复制代码
另外一种就是强制 try!
但你要确保 checkPassword
能是一个正常的函数返回
try! checkPassword("sekrit")
print("OK!")
复制代码
可选初始化失败init? 方法
struct Person {
var id: String
init?(id: String) {
if id.count == 9 {
self.id = id
} else {
return nil
}
}
}
复制代码
定义的Person 只有当接收的string 是9位数的时候才能初始化成功,其他时候返回的是一个nil
as?
class Animal { }
class Fish: Animal { }
class Dog: Animal {
func makeNoise() {
print("汪汪!")
}
}
复制代码
let pets = [Fish(), Dog(), Fish(), Dog()]
复制代码
pets 里面有很多小动物,当我们想找到Dog 对象时候,可以使用as? Dog
方法进行类型转化
for pet in pets {
if let dog = pet as? Dog {
dog.makeNoise()
}
}
复制代码
总结
- Optionals 让我们以清晰和明确的方式表示值的缺失
- 我们可以使用
if let
或者guard let
进行拆包 - 可以使用
!
进行强制拆包 - 可以使用 ?? 提供一个默认值
- 可选链语法 .? 让调用更简单和安全
- 可以使用
try?
转化一个会抛出异常返回值函数,或者强制try!
进行异常处理 - 如果你想要初始化方法失败,,使用
init?()
弄一个可选项初始化 - 你可以使用类型转化,
as
将一种类型转化成另一种类型