swift2.0 學習筆記Fifteen

enum VendingMachineError:ErrorType{

    case InvaildSelection //選擇無效

    case InsufficientFunds(coinsNeeded:Int) //金額不足

    case OutOfStock //缺貨無效

}


enum GetJSONError: ErrorType {

    case Forbidden, NotFound

}

struct Item {

    var price:Int

    var count:Int

}

class ViewController: UIViewController {

    

    func getJSON(aaa:Int) throws -> String {

        let a = aaa

        if a == 403 {

            throw GetJSONError.Forbidden

        }

        else if a == 404 {

            throw GetJSONError.NotFound

        }

        return "return JSON String Success"


    }

    

    

    

    var inventory = [

        "Candy Bar":Item(price: 12, count: 7),

        "Chips":Item(price: 10, count: 4),

        "Pretzels":Item(price: 7, count: 11)

    ]

    var coinsDeposited=4

    func dispenseSnack(snack:String){

        print("Dispensing\(snack)")

    }

    func vend(itemNamed name:String) throws{

        guard var item=inventory[name] else{

            throw VendingMachineError.InvaildSelection

        }

        guard item.count > 0 else{

            throw VendingMachineError.OutOfStock

        }

        guard item.price <= coinsDeposited else{

         

            throw VendingMachineError.InsufficientFunds(coinsNeeded: item.price - coinsDeposited)

        }

        coinsDeposited -= item.price

        --item.count

        inventory[name]=item

        dispenseSnack(name)

    }

    //錯誤處理

    //錯誤處理是響應錯誤以及從錯誤中恢復的過程。

    //可選類型用來表示值可能爲空,但是當執行失敗的時候,通常要去了解此次失敗是由何引起,代碼中就可以做出與之相應的反應

    //swift中,錯誤用遵循ErrorType協議類型的值來表示。這個空協議表示一種可以用做錯誤處理的類型。

    //throws關鍵字來標識一個可拋出錯誤的函數,方法或是構造器。在函數聲明中的參數列表之後加上throws,如果這個函數還有返回值類型,throws關鍵詞需要寫在箭頭的前面

    

    //一個throwing函數從其內部拋出錯誤,並傳遞到該函數被調用時所在的區域中

    //只有throwing函數可以傳遞錯誤。任何在某個非throwing函數內部拋出的錯誤只能在此函數內處理

    override func viewDidLoad() {

        super.viewDidLoad()

        

                do{

                    try vend(itemNamed: "Pretzels")

                    

                } catch VendingMachineError.InvaildSelection {

                    print("InvaildSelection")

                } catch VendingMachineError.OutOfStock {

                    print("OutOfStock")

                } catch VendingMachineError.InsufficientFunds(let myCoinsNeed){

                    print(myCoinsNeed)

                }catch{

                    print("error catched!")

                } //3

        

        

        do{

            let json = try getJSON(404)

            print(json)

        } catch GetJSONError.Forbidden {

            print("403 Forbidden")

        } catch GetJSONError.NotFound {

            print("404 Not Found")

        } catch {

            print("error catched!")

        }//404 Not Found

        

        

        //將錯誤轉換成可選值

        //可以使用try?通過將其轉換成一個可選值來處理錯誤。如果在評估try?表達式時一個錯誤被拋出,那麼這個表達式的值就是nil

        let json = try? getJSON(404) //如果不加問號則會報錯:Errors thrown from here are not handled

        print(json)//nil

        

        //let json = try? getJSON(404)等價於:

        let json2 : String?

        do{

          json2 = try getJSON(404)

        }catch{

          json2 = nil

        }

        print(json2)//nil

        

        

        //使錯誤傳遞失敗

        //有時你知道某個throwing函數實際上運行時是不會拋出錯誤的。在這種條件下,可以在表達式前面寫try!來使錯誤傳遞失敗,並且調用包裝在一個運行時斷言中來斷定不會有錯誤輸出。如果實際上確實拋出了錯誤,就會得到一個運行時錯誤

        

        //指定清理操作

        //可以使用defer語句在代碼執行到要離開當前的代碼段之前去執行一套語句。該語句讓你能夠做一些應該被執行的必要清理工作。defer語句將代碼的執行延時到當前的作用域之前。

        

        

    }

//    func processFile(filename:String)throws{

//        if exists(filename){

//            let file = open(filename)

//            defer{

//                close(file)

//            }

//            while let line = try file.readline(){

//                //處理文件

//            }

//            //作用域的最後調用close(file)

//        }

//    }

    

    

//    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

//        //保存觸摸起始位置

//       let point : CGPoint  = ((touches as NSSet).anyObject()?.locationInView(self.view))!

//         maskLayer.frame=CGRectMake(point.x-50,point.y-50, 100,100)

//    }

    

    //UITouch的屬性和方法:

    //view :屬性,觸摸始於那個視圖

    //window:屬性,觸摸始於那個窗口

    //locationInView:方法,觸摸在指定視圖中的當前位置

    //previousLocationView:方法,觸摸在指定視圖中的前一個位置

//    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

//        //計算位移=當前位置-起始位置

//        let point:CGPoint  = ((touches as NSSet).anyObject()?.locationInView(self.view))!

//         maskLayer.frame=CGRectMake(point.x-50,point.y-50, 100,100)

//    }

//    

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章