//: Playground - noun: a place where people can play
import UIKit
/*
* 本节主要内容:
* 1.分析错误处理的三个阶段
* 2.三个阶段整合
*/
/* 目的: 针对不同错误情况, 反映不同的错误信息
* 1.错误描述: 一般枚举类型, 遵循协议Error
* 2.错误抛出: throw / throws
* 3.错误捕获(处理): do / try / catch
*/
// 阶段一: 错误描述
// 描述"自动贩卖机器"枚举类型(错误信息)
enum VendingMachineError: Error {
case InvalidSelection
case NotEnoughMoney(coinNeeded: Int)
case OutOfStock
// .......
}
// 阶段二: 错误抛出(函数定义/声明); exception
func canThrowError(name: String?) throws -> String {
guard name != nil else {
print("There is no such product.")
// 以前: return "no such"
throw VendingMachineError.InvalidSelection
}
return "You can buy it!"
}
// 阶段三: 错误捕获/处理
// 原来: var result = canThrowError(name: "Water")
// 较严格/完整的方式
do {
var result = try canThrowError(name: nil)
} catch {
print("Invalid Selection")
}
// 三个阶段结合样例
// 描述贩卖机器结构体
struct VendingMachine {
// 描述商品的结构体
struct Item {
// 描述商品类型枚举
enum ItemType: String {
case Water // "Water"
case Cola // "Cola"
case Juice // "Juice"
}
let type: ItemType
// 价格
let price: Int
// 个数
var count: Int
}
// 第一阶段: 错误描述
enum ItemError: Error {
case NoSuchItem // 没有改产品
case NotEnoughMoney(Int) // 返回不够的钱数
case OutOfStock // 卖完了
}
// 声明存储属性(字典)
var items = ["Mineral Water": Item(type: .Water, price: 5, count: 15), "Coca Cola": Item(type: .Cola, price: 7, count: 10), "Orange Juice": Item(type: .Juice, price: 10, count: 20)]
// 阶段二: 错误抛出 //mutating 只是表示可以在方法内部修改 结构体或者枚举的变量
mutating func vend(itemName: String, money: Int) throws -> Int {
guard var item = items[itemName] else {
throw ItemError.NoSuchItem
}
// 返回真正产品的价格
guard money >= item.price else {
throw ItemError.NotEnoughMoney(item.price)
}
guard item.count > 0 else {
throw ItemError.OutOfStock
}
item.count -= 1
// 找回钱数
return money - item.price
}
}
// 第三阶段: 错误处理
var machine = VendingMachine()
var pocketMoney = 15
// 方式一: 强制执行有throw方法;
// 风险: 如果有错误, 无法处理; 编译错误
pocketMoney = try! machine.vend(itemName: "Coca Cola", money: pocketMoney)
// 方式二: 尝试着执行有throw方法
// 缺点和优势: 如果有错误, 无法处理; 但是不会有编译错误
try? machine.vend(itemName: "Cola", money: pocketMoney)
// 方式三: do / try / catch
do {
pocketMoney = try machine.vend(itemName: "Cola", money: pocketMoney)
} catch VendingMachine.ItemError.NoSuchItem {
print("No such product.")
} catch VendingMachine.ItemError.NotEnoughMoney {
print("Not enough money.")
} catch VendingMachine.ItemError.OutOfStock {
print("Out of stock")
} catch {
print("Error.....")
}
import UIKit
// 课堂练习
struct Matrix {
// 声明行数和列数存储属性
let rows: Int, columns: Int
// 声明一维数组属性
var grid: [Double]
// init构造方法
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
let defaultValue = Double(self.rows) * Double(self.columns)
grid = Array(repeating: defaultValue, count: rows * columns)
}
// 判定参数有效性
func indexIsValid(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
// 使用assert断言, 判断传入参数的有效性
assert(indexIsValid(row: row, column: column), "Index is out of range.")
return grid[(row * columns) + column]
}
set {
assert(indexIsValid(row: row, column: column), "Index is out of range.")
grid[(row * columns) + column] = newValue
}
}
}
// 实例化
var matrix = Matrix(rows: 3, columns: 4)
// 获取第1行第2列数据
matrix[1, 2]
// 对第1行第1列赋值
matrix[1, 1] = 1000
// 验证越界情况, 显示assert断言错误信息
// matrix[3, 4]
Day05
回顾:
1. 枚举类型: 值类型; 自定义类型(声明 + 实例化)
1.1 基本语法:
enum EnumName {
case caseName1
case caseName2
}
1.2 rawValue: 元值; 声明阶段关联类型, 每个case默认有关联值(rawValue) —> case的值都是常量
enum EnumName: Int {
case caseName1 // 0
case caseName2 // 1
}
—> rawValue可以自定义值, 要求如下:
a. 值必须唯一
b. 只能关联: Int / Float / Double / String / Character
1.3 associated value: 关联值; 声明阶段每个case关联类型, 实例化阶段, 给关联的类型赋值. —> case的值都是变量
enum Shape {
case Square(side: Double)
case Rectangle(width: Double, height: Double)
case Circle(centerX: Double, centerY: Double, radius: Double)
case Point // 没有默认的值
}
// 实例化
var square = Shape.Square(side: 10)
var squareNew = Shape.Square(side: 20)
2. 结构体: 声明 + 实例化 + 添加属性和方法(自定义)
struct StructName {
var latitude: Double
var longitude: Double
mutating func functionName() {
latitude += 1.0 // 修改结构体的属性
}
}
var structInstance = StructName(latitude: 10.21, longitude: 11.432)
structInstance.latitude
今天内容:
· 结构体中init构造方法
· subscript语法(下标语法)
· 类
结构体中init构造方法
1. 引言: Int / Float / Double / String / Array / Dictionary都是结构体, 点语法获取属性/方法.
—> var imInt = Int(10) var imFloat = Float(10.5)
2. 样例: 为结构体添加init构造方法
[ 01_struct ]
—> 总结:
a. 默认init构造方法
b. 自定义init构造方法
/05_Swift/Day05/Day05-AM1.zip
3. 样例: 为结构体添加可失败的构造方法init?
[ 02_init_struct ]
4. 样例: 为结构体添加两种类型的属性(语法同样适用于类)
[ 03_property_subscript ]
—> 属性分类:
a. 存储型属性Stored Property: 存储值
b. 计算型属性Computed Property: set/get方法
—> 下标语法subscript
a. 例如: array[0], array[1], dictionary[0], structName[x]
—> 总结:
a. 计算型属性更加灵活, 更加直接
/05_Swift/Day05/Day05-AM2.zip
———————— 下午内容 ———————
1. 继续Demo03中的下标语法
—> 下标语法注意事项:
a. 针对对象: 枚举/结构体/类
b. 作用: 使用下标语法设置/获取属性的值
c. 语法: 函数和计算型属性结合
/05_Swift/Day05/Day05-PM1.zip
2. Error Handling(重点和难点)
2.1 例如: 没有任何错误信息提示
2.2 例如: 字符串转成整型 Int(“hello”) -> nil(最直接/最简单的错误信息)
2.3 Error Handling错误处理机制: 面向终端用户以及程序员机制, 显示错误原因信息;
2.4 样例: 实现错误处理机制
[ 04_error_handling ]
/05_Swift/Day05/Day05-PM2.zip
课堂练习:
[ 05_practice ]
1).需求: 声明一个描述二维数组的结构体Matric, 使用下标语法, 通过两个下标(行,列)访问一维数组的元素
2).要求: init构造方法(初始化一维数组), init方法的参数两个(行数和列数); 处理越界情况
3).结果: matric[1, 5] -> 获取二维数组的第1行第5列元素
Day05知识点总结:
1. 掌握结构体可失败构造函数本质和语法
2. 掌握结构体存储型属性和计算性属性语法和适用场景
3. 理解下标subscript语法
4. 掌握三种错误处理的方式
Swift 系统学习 22 分析错误的三个阶段 (枚举和结构体相关)
最新推荐文章于 2022-10-24 20:14:49 发布