swift学习笔记之-错误处理
//错误处理
import UIKit
/*错误处理(Error Handling):响应错误以及从错误中恢复的过程
在 Swift 中,错误用符合ErrorType协议的类型的值来表示。这个空协议表明该类型可以用于错误处理,Swift 的枚举类型尤为适合构建一组相关的错误状态,枚举的关联值还可以提供错误状态的额外信息
抛出错误使用throw关键字,如:throw VendingMachineError.InsufficientFunds(coinsNeeded: 5)
处理错误:
1.某个错误被抛出时,附近的某部分代码必须负责处理这个错误,例如纠正这个问题、尝试另外一种方式、或是向用户报告错误
2.Swift 中有4种处理错误的方式。你可以把函数抛出的错误传递给调用此函数的代码、用do-catch语句处理错误、将错误作为可选类型处理、或者断言此错误根本不会发生
3.为了标识出会抛出错误的地方,在调用一个能抛出错误的函数、方法或者构造器之前,加上try关键字,或者try?或try!这种变体
4.用 Do-Catch 处理错误:
a.如果在do子句中的代码抛出了一个错误,这个错误会与catch子句做匹配,从而决定哪条子句能处理它。
b.如果一条catch子句没有指定匹配模式,那么这条子句可以匹配任何错误,并且把错误绑定到一个名字为error的局部常量
c.catch子句不必将do子句中的代码所抛出的每一个可能的错误都作处理,如果所有catch子句都未处理错误,错误就会传递到周围的作用域,但错误最终都要被处理。
do {
try ...
}catch ... {
...
}catch ... {
...
}
用 throws 函数传递错误:
1.为了表示一个函数、方法或构造器可以抛出错误,在函数声明的参数列表之后加上throws关键字。一个标有throws关键字的函数被称作throws函数。如果这个函数指明了返回值类型,throws关键词需要写在箭头(->)的前面。如:func canThrowErrors() throws -> String
2.一个 throws 函数可以在其内部抛出错误,并将错误传递到函数被调用时的作用域。
3.只有 throws 函数可以传递错误。任何未声明为throws的函数内部抛出的错误只能在函数内部处理!
将错误转换成可选值:
1.可以使用try?通过将错误转换成一个可选值来处理错误。如果在评估try?表达式时一个错误被抛出,那么表达式的值就是nil
func fetchData() -> Data? {
if let data = try? fetchDataFromDisk() {
return data
}
if let data = try? fetchDataFromServer() {
return data
}
return nil
}
禁用错误传递:在表达式前面写try!来禁用错误传递,这会把调用包装在一个断言不会有错误抛出的运行时断言中。如果实际上抛出了错误,你会得到一个运行时错误。
如: let photo = try! loadImage("./Resources/John Appleseed.jpg") 虽然loadImage函数为throws函数,但此处通过给定的参数调用时不会抛出错误,所以用禁用错误传递try!
指定清理操作:
1.使用defer语句在即将离开当前代码块时执行一系列语句,该语句让你能执行一些必要的清理工作,不管是以何种方式离开当前代码块的——无论是由于抛出错误而离开,还是由于诸如return或者break的语句,
2.defer语句将代码的执行延迟到当前的作用域退出之前
3.该语句由defer关键字和要被延迟执行的语句组成。延迟执行的语句不能包含任何控制转移语句,例如break或是return语句,或是抛出一个错误。延迟执行的操作会按照它们被指定时的顺序的相反顺序执行
func processFile(filename: String) throws {
if exists(filename) {
let file = open(filename)
defer {
close(file) //defer内的语句将被延迟执行,执行多语句时反顺序执行
}
while let line = try file.readline() {
// 处理文件代码
}
//defer内的 close(file) 在这里才会被调用,即作用域的最后。
}
}
*/
//===================用枚举定义错误类型信息=====
enum VendingMachineError: ErrorType {
case InvalidSelection //选择无效
case InsufficientFunds(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 dispenseSnack(snack: String) {
print("Dispensing \(snack)")
}
func vend(itemNamed name: String) throws {
//throws关键字,定义了该函数可抛出throw错误,在调用此方法的地方,必须要么直接处理这些错误,使用do-catch语句,try?或try!;要么继续将这些错误传递下去
//guard ... else{ ... } ,表达式为false时执行else,为true时跳过else的代码,执行后面的代码
guard var item = inventory[name] else {
throw VendingMachineError.InvalidSelection //这里的throw 抛出指定错误类型到外部,通过其它方式处理该错误
}
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)
}
}
let favoriteSnacks = [
"Alice": "Chips",
"Bob": "Licorice",
"Eve": "Pretzels",
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
let snackName = favoriteSnacks[person] ?? "Candy Bar"
//空合运算符"a ?? b",a必须为可选类型,若a有值则取值,无值则取b的值,类型必须一样
try vendingMachine.vend(itemNamed: snackName)
}
//=======do-catch=========
var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
try buyFavoriteSnack("Alice", vendingMachine: vendingMachine)
} catch VendingMachineError.InvalidSelection {
print("Invalid Selection.")
} catch VendingMachineError.OutOfStock {
print("Out of Stock.")
} catch VendingMachineError.InsufficientFunds(let coinsNeeded) {
print("Insufficient funds. Please insert an additional \(coinsNeeded) coins.")
}
// 打印 “Insufficient funds. Please insert an additional 2 coins.”
swift学习笔记之-错误处理的更多相关文章
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- Swift学习笔记(一)搭配环境以及代码运行成功
原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...
- swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记4——扩展、协议
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- 记录:swift学习笔记1-2
swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...
- swift学习笔记3——类、结构体、枚举
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习笔记一
最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...
随机推荐
- JAVA笔记 之 JDK新特性
JDK1.5新特性1.泛型(Generics) 为集合(collections)提供编译时类型安全,无需每刻从Collections取得一个对象就进行强制转换(cast) 2.增强的for循环(for ...
- PowerDesigner 16.5对SQL Server 2012 生成数据库时"不支持扩展属性"问题
团队合作设计一套系统数据模型,创建了PDM后,Table.View.Store Procedure等都创建好了,且创建了多个Schema方便管理这些数据库对象,但Table.view.Column等对 ...
- 打包并压缩seajs代码
背景 seajs是一款优秀的模块开发插件,但是当我们使用它来进行模块化开发的时候,由于它的每个模块的加载都会进行一次http请求,那么当模块数量倍增的时候,会拖慢页面的加载速度. 通常我们为了能加快页 ...
- 新浪微博OAuth2.0的用法
最近学习Android开发,照着视频开发新浪微博,但是视频里的介绍的是OAuth1.0的授权方式,试了半天发现用不了. 原来现在一般没审核的用户只能使用OAuth2.0了,视频教学里的方法已经过时了. ...
- MyBatis知多少(14)分散的数据库系统
任何一个重要的数据库无疑都会拥有不止一个依赖者.即使该数据库只是简单地被两个Web 应用程序所共享,也有许多事情需要考虑.假设有一个名为网上购物车的Web应用程序,它使用了一个包含类别代码的数据库.就 ...
- JS对象的几个方法介绍
1.hasOwnProperty 判断是不是对象自身的属性,如果是继承的返回false否则true function Fn(){ } Fn.prototype.num = 10; var obj = ...
- linux常用
一.命令 1.查指令,man, info, /usr/share/doc/: 2.文档,nano lyp.txt: 3.谁在线,who: 4.数据同步写入硬盘,sync: 5.显示档案,ls: 6.目 ...
- js实现无刷新表单提交文件,将ajax请求转换为form请求方法
最近在做项目的时候遇到一个需要上传文件的需求,因为ajax请求是无法上传二进制文件流的,所以只能用form表单提交,而form提交有一个问题就是会使页面刷新,本文解决了form表单提交文件时页面刷新的 ...
- 使用Service.Stack客户端编写redis pub sub的方法
pub相对简单 client.PublishMessage("channel", "msg"); sub有2种方法 方法1 var subscription ...
- spring websocket源码分析
什么是websocket? 摘录于wiki[1]: WebSocket is a protocol providing full-duplex communication channels over ...