文章摘要
GPT 4
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

说在前面

Java社区中,针对 null 的讨论特别多,甚至有一种论点是:null是失败的设计,因为NPE(空指针异常)问题造成了很多损失。

swift作为一种类型安全的语言,同样考虑到这个问题,在这边它叫做 nil ,于是在使用可能为空的值时,必须显式地处理值不存在的情况,例如通过可选绑定、强制解包或者提供默认值等方式。

可选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 定义一个可能为空的字符串变量
var optionalString: String?

// 尝试为可选项赋值
optionalString = "Hello, Swift!"

// 可选绑定
if let unwrappedString = optionalString {
print("Value exists: \(unwrappedString)")
} else {
print("Value is nil")
}

// 强制解包(不推荐,除非能确保不为 nil )
let forcedString = optionalString!
print(forcedString)

在 Swift 中,可选项(Optionals)用于表示一个值可能存在也可能不存在的情况。
可选项让您能够明确处理值缺失的情况,避免了在其他语言中可能出现的空指针异常等错误。
可选项有两种可能的状态:包含一个值(称为 “已包装”)或者不包含值(称为 “nil”)。
声明一个可选项的方式是在类型后面加上一个问号 ? ,例如 var someValue: Int?
要访问可选项中包含的值,需要进行可选绑定(Optional Binding)或者强制解包。可选绑定使用 if letwhile let 语句来安全地访问值,如果可选项不为 nil 则执行相应的代码块。强制解包使用 ! ,但如果可选项为 nil 会导致运行时错误,所以强制解包要非常小心,确保可选项不为 nil

guard语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func processOptionalValue(optionalValue: Int?) {
guard let unwrappedValue = optionalValue else {
print("可选项为 nil,无法处理")
return
}
// 在这里使用解包后的值 unwrappedValue 进行后续操作
print("解包后的值: \(unwrappedValue)")
}

let myOptional: Int? = 5
processOptionalValue(optionalValue: myOptional)

let anotherOptional: Int? = nil
processOptionalValue(optionalValue: anotherOptional)

在上述代码中,guard 语句用于确保可选项有值,如果没有值(为 nil )则执行 else 分支中的代码,通常是提前返回或者进行错误处理。如果可选项有值,解包后的值可以在 guard 语句后面的代码中使用。

空合并??

1
2
3
4
5
6
7
8
9
var optionalString: String?

// 假设 optionalString 为 nil
let result = optionalString?? "默认值"
print(result) // 输出 "默认值"

optionalString = "有值"
let newResult = optionalString?? "默认值"
print(newResult) // 输出 "有值"

在 Swift 中,空合并操作符(Nil Coalescing Operator)是 ?? 。它用于提供一个默认值,如果可选项为 nil ,则使用默认值
在上述示例中,当 optionalString 为 nil 时,result 的值为 “默认值” ;当 optionalString 有值时,newResult 的值为 optionalString 所存储的值。

可选链

1
2
3
4
5
6
7
8
9
10
11
12
class Person {
var address: Address?
}

class Address {
var streetName: String?
}

let person = Person()

// 使用可选链访问可能为 nil 的属性
let street = person.address?.streetName

可选链(Optional Chaining)是一种用于安全地访问和调用可能为 nil 的可选项的属性、方法和下标。

通过可选链,如果可选项为 nil,整个表达式会立即返回 nil,而不会导致运行时错误。这使得在处理可能为空的对象时,代码更加简洁和安全。

try?

1
2
3
4
5
6
7
8
9
10
11
func mightThrowError() throws -> String {
// 假设这里可能抛出错误
throw NSError(domain: "Some Error", code: 0, userInfo: nil)
}

let result = try? mightThrowError()
if result == nil {
print("发生错误")
} else {
print("没有错误,结果: \(result!)")
}

try? 用于在 Swift 中进行错误处理,它会尝试执行一段可能抛出错误的代码。如果执行过程中没有抛出错误,try? 会返回可选类型的值;如果抛出了错误,try? 会返回 nil

总结

  • 可选类型让我们能够表示数据缺失的情况。
  • 所有非可选的内容内部肯定都有一个值。
  • 解包操作会查看可选类型内部:如果有值,就会返回该值。
  • if let 会在可选类型有值的情况下运行代码;guard let 则会在可选类型没有值的情况下运行代码。
  • ?? 会解包并返回可选类型的值,或者返回一个默认值来替代。
  • 可选链 可以读取另一个可选类型内部的可选类型!
  • try? 能够转换会抛出异常的函数,使其返回一个可选类型。

课后作业

  • 编写一个接受可选整数数组的函数,并返回随机的整数之一。
  • 如果数组丢失或为空,则返回一个范围1到100的数字
  • 用一行代码编写您的函数。
1
2
3
func returnRandomNum(arr : [Int]?)-> Int{
arr?.randomElement() ?? Int.random(in: 0...100)
}