Swift学习03:swift中guard语句

张建 lol

前言

对异常的正确处理能够明确反映在代码执行中出现的问题,使得接下来的debug快速定位问题所在的地方,提高debug效率,同时也能对不同情况做出不同响应

异常处理的历史由来

  • swift1.0:cocoa touch 的 NSError,swift没有真正自己的异常处理机制

  • swift2.0:加入 ErrorType protocol

  • swift3.0:改名 Error protocol

swift3.0 Error protocol 的使用

首先定义一个枚举,遵循协议 Error

1
2
3
4
5
enum MyError : Error {
  case one
  case two
  case three
}

Error Handing 异常处理

swift2.0 引入了 guard、try、do catch、throw、throws六个关键字 组成的异常处理机制

guard

  1. 什么是guard?

guardswift2.0 推出的新的判断语句的用法。guard 语句和 if 语句类似,都是根据关键字之后的表达式的布尔值决定下一步执行什么。和if语句不同的是,guard语句只有一个代码块,而if语句可有多个代码块。(如 if 、else if、 else)

  1. guard有什么作用?

顾名思义,guard 是作为 保卫 作用而存在的。当你不满足我的要求,那么请您出去;如果满足,则执行下一步操作。

  1. guard与if相比

if 语句相同的是,guard 也是基于一个表达式的 布尔值 去判断一段代码是否该被执行。与 if 语句不同的是,guard 只有在条件不满足的时候才会执行这段代码。你可以把 guard 近似的看做是 Assert,但是你可以优雅的退出而非崩溃。

  1. guard 用法?
1
2
3
4
guard 条件 else {
// 条件不成立执行
}
// 条件成功往下执行
  • guard 语句条件为 false 时,执行大括号里面的代码
  • guard 语句条件为 true 时,跳过guard语句

举例:登录的时候判断用户名和密码是否为空

  • 私有方法判断用户名和密码是否为空
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private func login(_ info:[String:String]) {
let username = info["username"]!
let password = info["password"]!
// 判断是否有用户名,如果有往下执行,没值执行括号里的内容
guard !username.isEmpty else {
print("请输入用户名");
return
}
// 判断是否有密码
guard !password.isEmpty else {
print("请输入密码");
return;
}
print("用户名:\(username)","密码:\(password)");
}

  • 调用
1
login(["username":"zj","password":""])
  • 查看打印结果
1
请输入密码

do catch

  • do 后面大括号中的代码抛出了异常,就会执行 catch

  • do 后面大括号中的代码没有抛出异常,就不会执行 catch

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

let data = Data()
doCatch(data)
}

func doCatch(_ data: Data) {
do {
// 这里的代码抛出了异常,就会执行catch
let dict = try JSONSerialization.jsonObject(with: data)
print(dict)
}catch {
// catch中默认提供error信息,当序列化不成功时,但会error
print(error)
}
}

======
Error Domain=NSCocoaErrorDomain Code=3840 "Unable to parse empty data." UserInfo={NSDebugDescription=Unable to parse empty data.}

由于data是空的,解析异常,执行catch

throws和throw

  • 使用 throws 放在参数列表后面 表明 一个方法有 异常抛出
1
2
3
func 方法名字(参数列表) throws -> 返回值类型 {
内部使用 thorw抛出异常
}

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

do {
var str: () = try test(str: "three")
print(str)
}catch MyError.one {
print("MyError.one")
}catch MyError.two {
print("MyError.two")
}catch {
print(error)
}
}

func test(str: String) throws -> void{
if str == "one" {
throw MyError.one
}else {
throw MyError.two
}
}

=====
MyError.two

try、try?、try!

  1. try
  • 出现异常处理异常

  • try 配合 do catch 使用

  1. try? (常用方式)
  • 不处理异常

  • 使用这个关键字返回一个 可选值类型

  • 如果有异常,返回 nil

  • 如果没有异常,返回 可选值

举例:将服务器返回的JSON数据反序列化成字典

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
func tryTest() {
// 字典
let jsonstr = "{\"status\":\"1\",\"data\":{\"udid\":\"5bce8b974adbc6a60858d41657f1761305f62ce9\",\"time\":\"1580546728\",\"orderid\":\"20200201164519672\"}}"
let jsondata = jsonstr.data(using: .utf8)

let success = try? JSONSerialization.jsonObject(with: jsondata!, options: .mutableContainers) as Any
print(success!)
}

========
Optional({
data = {
orderid = 20200201164519672;
time = 1580546728;
udid = 5bce8b974adbc6a60858d41657f1761305f62ce9;
};
status = 1;
})
  1. try! (不建议使用,非常危险)
  • 不让异常传播,一旦出现了异常,那么程序会停止
1
2
3
4
5
6
// 原生解析方法
let dicArr = try! JSONSerialization.jsonObject(with: jsonData!, options: .allowFragments) as! [[String:AnyObject]]
print("打印所有数据:\(dicArr)")

=====
[["id": 3], ["id": 5]]

Assert 断言

  1. 有什么作用?

不符合条件 的主动崩溃。

  1. 用法
1
2
3
4
5
6
private func assertTest(_ someValue: Bool) {
// 一些奇怪的错误发生
assert(someValue, "some strange error happen")
// 打印
print("zj")
}
  • someValue 时会继续执行下面的代码,打印 zj

  • 如果为 ,则会抛出异常,会让程序终止在此处,同时打印出信息,其中文件路径和异常代码所在的行数编译器会自动打出:

1
2023-04-23 19:14:57.417918+0800 Assert[40173:730298] Assertion failed: some strange error happen: file Assert/ViewController.swift, line 20

NSExcetption

  • Post title:Swift学习03:swift中guard语句
  • Post author:张建
  • Create time:2023-02-03 19:54:25
  • Post link:https://redefine.ohevan.com/2023/02/03/Swift/Swift学习03:Error Handing错误处理/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.