错误处理

308 阅读1分钟
  1. 四种方式处理错误
    1. 继续用throwing函数抛出错误(如果在一个方法内部不想处理错误,这时候想继续抛出错误可以用try去执行这个函数返回值类型是trows。)
    2. do,try,catch处理错误(一个函数可以在内部处理错误)
    3. 将错误变为可选类型(想把抛出的错误转成可选类型,这时候用try?trowErrorMethod,它将会返回两种类型,一种是nil就是出错,还有一种是真正无错的返回值类型)
    4. 禁止错误传递 (如果可以确保一个方法不会抛出错误,那么可以禁止错误抛出try!trowErrorMethod)
enum VendingMachineError: Error {
    case invalidSelection
    case infufficientFounds(coinsNeeded:Int)
    case outOfStock
}

struct Item {
    var price: Int
    var count: Int
}

class VendingMachine {
    var inventory = [
        "Candy Bar": Item(price: 12, count: 7),
        "Chips": Item(price: 10, count: 4),
        "Pretzels": Item(price: 7, count: 11)
    ]
    var coinsDeposited = 0

    func vend(name: String)throws -> Bool {
        guard var item = inventory[name] else {
            throw VendingMachineError.invalidSelection
        }

        guard coinsDeposited >= item.count else {
            throw VendingMachineError.infufficientFounds(coinsNeeded: item.count - coinsDeposited)
        }

        guard item.count > 0 else {
            throw VendingMachineError.outOfStock
        }

        item.count -= 1
        inventory[name] = item

        return true
    }
}

//1. throwing函数继续抛出错误
struct Purchased {
    var name: String
    init(name: String, machine: VendingMachine) throws{
        self.name = name
        try machine.vend(name: name)
    }
}

//2. do,try,catch处理
do {
    let a = try Purchased(name: "sts", machine: VendingMachine())
    print(a)
} catch VendingMachineError.invalidSelection {
    print("无效选择")
}catch {
    print(error)
}

do {
    let machine = VendingMachine()
    machine.coinsDeposited = 5
    let a = try machine.vend(name: "Candy Bar")
    print(a)
} catch VendingMachineError.invalidSelection {
    print("无效选择")
}catch {
    print(error)
}

//3. 将错误转成可选值
let machine = VendingMachine()
machine.coinsDeposited = 7
let ret = try? machine.vend(name: "Pretzels")
print(ret as Any)

//4. 禁用错误传递
let machine1 = VendingMachine()
machine1.coinsDeposited = 100
let ret1 = try! machine1.vend(name: "Pretzels")
print(ret1)

  1. 延时执行defer
    1. 延时执行代码,在函数调用完毕后执行
    2. 往往做一些清理工作
//伪代码
func dealFile(fileName: String){
    if exists(fileName) {
        let file = open(fileName)
        defer {
            close(fileName)
        }
        
        //处理文件
    }
}

var a = 3
func test() -> Int {
    defer {
        a = 5
    }
    return a
}

print(test())
print(a)
//打印如下
//3
//5