如何在 swift println 错误中进行错误处理

Swift2.0-异常处理(Exception handler)
关于我们为什么要使用异常处理,请看百度百科为我们作出的描述,想要更详细的资料请点
异常处理,英文名为exceptional handling, 是代替日渐衰落的error code方法的新法,提供error code 所未能具体的优势。异常处理分离了接收和处理错误代码。这个功能理清了编程者的思绪,也帮助代码增强了可读性,方便了维护者的阅读和理解。 异常处理(又称为错误处理)功能提供了处理程序运行时出现的任何意外或异常情况的方法。异常处理使用 try、catch 和 finally 关键字来尝试可能未成功的操作,处理失败,以及在事后清理资源。
异常处理,是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况(即超出程序正常执行流程的某些特殊条件)。
它有功能强大的控制流语句,像`do`、`try`、`catch`、`guard`和`defer`。我们能够使用这些关键字去操控我们的代码,更精确地执行我们的代码。
以上摘自百度百科:
关联,在Objective-C中,异常处理一般都是使用NSError类接收异常和抛出异常,使用方法像这样
NSError *error =
NSString *string = [[NSString alloc] initWithContentsOfFile:@&filePath& encoding:NSUTF8StringEncoding error:&error];
if (error != nil) {
// Exception handle
NSLog(@&Erorr is %@&, error);
// Code...
不得不说,Swift的异常处理更为优雅,下面会重点介绍。
你可以在github上下载这个
构建异常类型
我们可以构建自己的异常类型,它只是一个枚举,遵循ErrorType,像是这样
enum MyErrorHandling: ErrorType {
case error1
case error2
定义函数可抛出异常
这里值得一提的是,只有函数才能够抛出异常。我们需要在参数后和返回值前加上throws关键字,并用guard捕捉异常,用throw抛出异常。
func myLoad(item: String?) throws -& String {
guard let newItem = item else {
throw MyErrorHandling.error1
return newItem
guard: guard必须与else配合使用,只有当guard审查的条件成立,guard之后的代码才会执行,否则抛出异常。
捕获/处理异常
我们使用do-try-catch去获取并处理异常
try myLoad(nil)
print(&error&)
如果只包含一个catch语句,那么所有的错误都会在这个catch中执行,我们能够捕抓其错误信息
try myLoad(nil)
} catch let error as NSError {
print(error)
我们在使用catch时,它是能够进行模式匹配的,我们能够进行更精准的错误匹配处理
try myLoad(&test&)
} catch MyErrorHandling.error1 {
print(&error1&)
} catch MyErrorHandling.error2 {
print(&error2&)
如果我们不需要捕抓错误,那么我们可以使用try!或try?去执行该函数
try? myLoad(nil)
不建议使用try!,使用try?会更加安全。因为如果当有错误捕抓到时,程序会直接崩溃
Defer(延迟执行)
那么我们何时需要使用到defer?这里使用官方的例子,比如我们需要读取某文件内容并处理,你需要打开这个文件,最后你需要关闭这个文件。当一切顺利的时候,程序一直往下运行,文件也将会被关闭。那么当中间出现一些错误呢?例如在某个环节执行失败了,但是你依然是需要去关闭该文件,在此defer就表现得很强大了。在这个例子中,我们可以把关闭文件的代码放到defer里面,在defer里的代码无论是函数执行成功或失败都会被执行。
func myLoad(item: String?) throws -& String {
print(&Handle 1&)
print(&Handle 2&)
guard let newItem = item else {
throw MyErrorHandling.error1
return newItem
需要注意的是,defer语句可以有多个,它们的执行顺序是Handle 1 -& Handle 2。不难理解,它们的执行顺序是先进后出的。
这里再说一下,你可以在github上下载这个
博文作者:GarveyCalvin
博文出处:
本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作!
阅读(...) 评论()【个人】学Swift语言过程中遇到的问题、解决方案
1.Swift语言中nil表示值缺失,可以在程序中联合使用if和let来处理值缺失的情况,具体方法是在类型后面加一个问号"?"来标记这个变量的值是可选的。
var optionalString:
String? = "Hello"
optionalString ==
var optionalName:
String? = "John Appleseed"
var greeting =
if let name =
optionalName {
greeting = "Hello,
2.布尔表达式:一段代码的声明并判断,它最终只有true(真)和false(假)两个取值。
3.Switch中case let x
x.hasSuffix("pepper"):代表变量名中后缀包含pepper,就执行语句。而x.asPrefix(""):代表前缀。
4.for-in遍历字典:
eg(1).求字典中最大的值:
let interestingNumbers =
& "Prime": [2,3,5,7,11,13],
& "Fibonacci": [1,1,2,3,5,8],
& "Square": [1,4,9,16,25]
var largest =
for (kind, numbers) in
interestingNumbers {
& for number in numbers {
& & & if number
& largest {
& & largest = number
temp& in str {
& println(temp)
//输出结果为:str中的字符按顺序一排一个输出。
var dic = ["key1":"ios"
,"key2":"swift" ,"key3":"android"]
for (key,value) in
println("key:\(key),
value:\(value)")
//输出结果的顺序是随机的,除非字典里增值或减值,那顺序可能会改变,否则是不变的。
5.循环语句for
in中的三点(...)代表一个范围,例如for i in 0...3{},代表 i
逐一取值0,1,2,3做循环。ps.两点(..)的格式已被新版本取消使用。
6.func Test(numbers:
Int...) -& Int
{}中三个点代表可变数目形参列表,也就是说调用该函数时可以传递不定数目的实参。
7.Swift&使用typealias关键字定义类型别名.
typealias Point = (Int,
let origin: Point = (0,
8.Swift数组格式:
一维数组: let someArray:
[类型] = […]
等价于:let someArray:
Array&类型& = […]
二维数组: let someArray:
[[类型]] = [[…],[…]]
等价于:let
someArray:&Array&&=
[[…],[…]]
三维数组: let someArray:
[[[类型]]] = [[[…],[…]],[[…],[…]]]
等价于:let someArray:
Array&类型&&& = [[[…],[…]],[[…],[…]]]
9.Swift的可选类型(参数名:&&类型?和!):
的可选类型可以让你暗示任意类型的值缺失,并不需要一个特殊值。在可选类型的实例中包含一个值,则可以用后缀操作符“!”来获取该值,若使用“!”操作符获取值为nil的可选项会导致运行错误。
let possibleNumber =
let convertedNumber =
possibleNumber.toInt()
// convertedNumber
被推测为类型 "Int?", 或者类型 "optional Int"
因为toInt方法可能会失败,所以它返回一个可选类型(optional)Int,而不是一个Int。一个可选的Int被写作Int?而不是Int。问号暗示包含的值是可选类型,也就是说可能包含Int值也可能不包含值。(不能包含其他任何值比如Bool值或者String值。只能是Int或者什么都没有。)
10.ps.下面声明的代码时等价:
var optionalInteger:
var optionalInteger:
ImplicitlyUnwrappedOptional
11.可选类型String和隐式解析可选类型String之间的区别:
let possibleString:
String? = "An optional string."
possibleString!)& // 需要感叹号来获取值
let assumedString:
String! = "An implicitly unwrapped optional string."
assumedString)& // 不需要感叹号
12.在Swift语言中,整数字面量可以被写作为如下所示的形式:
一个十进制数,没有前缀。
一个二进制数,前缀是0b。
一个八进制数,前缀是0o。
一个十六进制数,前缀是0x。
13.在Swift语言中,浮点字面量有一个可选的指数,在十进制浮点数中通过大写或者小写的e来指定,在十六进制浮点数中通过大写或者小写p来指定。
(1)如果一个十进制数的指数为exp,那这个数相当于基数和10^exp的乘积。
1.25e2 表示 1.25 * 10^2,
等于 125.0。
(2)如果一个十六进制数的指数为exp,那这个数相当于基数和2^exp的乘积。
0xFp2 表示 15 * 2^2,
等于60.0。
14.断言的使用:
断言是通过判断条件是否成立,来决定代码改不改继续往下执行。
let age = -3
assert(age &= 0,
//因为age & 0
,所以断言会触发
15.Character即char参数类型,两个Character类型的值相加会形成新的String类型的值。
16.不同于C语言和Objective-C,在Swift程序中可以对浮点数进行求余。
17.对负数求余的例子:
let a = 9 % 2 & // a =
let b = 9 % -2 &// b =
let c = -9 % 2 &// c =
let d = -9 % -2 // d = -1
18.恒等运算符
因为类是引用类型,有可能有多个常量和变量在后台同时引用某一个类实例。(对于结构体和枚举来说,这并不成立。因为它们作值类型,在被赋予到常量,变量或者传递到函数时,总是会被拷贝。)
如果能够判定两个常量或者变量是否引用同一个类实例将会很有帮助。为了达到这个目的,Swift
内建了两个恒等运算符:
等价于 ( === )
不等价于 ( !== )
以下是运用这两个运算符检测两个常量或者变量是否引用同一个实例:
if tenEighty ===
alsoTenTighty {
& println("tenTighty and alsoTenEighty refer to
the same Resolution instance.")
//输出 "tenEighty and
alsoTenEighty refer to the same Resolution
instance."&
请注意“等价于”(用三个等号表示,===)
与“等于”(用两个等号表示,==)的不同:
“等价于”表示两个类类型(class
type)的常量或者变量引用同一个类实例。
“等于”表示两个实例的值“相等”或“相同”,判定时要遵照类设计者定义定义的评判标准,因此相比于“相等”,这是一种更加合适的叫法。
19.二进制的“低八位、高八位;低四位、高四位”概念:
一般来说内存操作都是针对内存,也就是一个字节,8位。如果是16位的指令,就是同时操作连续的2个内存地址,将这连续的2个内存地址当成一个单位,所有就有高8位和低8位之分。由于计算机仅识别二进制描述的数字,所以对一个内存地址,也就是8位二进制,如:0000
就是高四位,0001就是低四位,当然2个内存地址,就是16位二进制,也就是:00
0001 就是高八位,就是低八位,每个八位中又分成高低四位。如:11
0101,换算成16进制就是:进制)---A(16进制),进制)---1(16进制)所以他的高八位就是A1,同样它的低八位就是F5。
20.原码、补码、反码概念:
原码:就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
[+1]原 = 0000
[-1]原 = 1000
反码:正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
[]原 = []反
[]原 = []反
补码:正数的补码与其原码相同;负数的补码是在其反码的末位加1。
[]原 = []反 =
[]原 = []反 =
21.位运算符概念:
~:按位取反运算符,对操作数的二进制每一位都取反。
&:按位与运算符,将参与运算的两数各对应的二进位相与,只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现(要照顾到负数的原因)。
|:按位或运算符,将参与运算的两数各对应的二进位相或,只要对应的两个二进位有一个为1时,结果位就为1,否则为0。参与运算的数以补码方式出现(要照顾到负数的原因)。
0b1111 = 0b1111
^:按位异或运算符,将参与运算的两数各对应的二进位相异或,只要当两对应的二进位相异时,结果为1,否则为0。参与运算的数以补码方式出现(要照顾到负数的原因)。ps.运用异或运算可以方便使两变量的数值交换。
&&:按位左移运算符,将运算数的各二进制位全部左移若干位,注意值向上、向下溢出。
&&:按位右移运算符,将运算数的各二进制位全部右移若干位,注意值向上、向下溢出。Ps.十六进制中每两个字符是8比特位,所以移动16位的结果是把0xCC0000变成0xCC。
22.xcode 6.1 swift 使用
dataWithContentsOfURL方法已改变:
以前写为:
var data = NSData.dataWithContentsOfURL(url!,
options: NSDataReadingOptions.DataReadingMapped, error:
var data = NSData(contentsOfURL: url!, options:
NSDataReadingOptions(), error: nil)
否则报错。
23.&Failed to instantiate the default view
controller for UIMainStoryboardFile 'Main' - perhaps the designated
entry point is not set?错误:可导致Xcode模拟器黑屏
原因是在StoryBoard中没有一个view
controller设置了Initial Scene,应在Storyboard中,选择一个view conroller作为story
board的第一启动界面。
24.Xcode开发的应用程序打开时,卡在进入页面(Xcode模拟器可以,真机调试显示错误),可能是设备需要联网才能进入界面。
25.溢出运算符:
超出数值类型的承载范围(称为上溢出或下溢出),编译器就会报错,这时就要用到溢出运算符。溢出运算符会对有效位进行截断,然后输出值,慎用。(溢出加法:&+;溢出减法:&-;溢出乘法:&*;溢出除法:&/;溢出求余:&%)
26.isEmpty属性的使用:判断字符串是不是空,返回布尔类型。
var str3:String = " 啊啊啊啊
if str3.isEmpty
& println("str3的值是空")
& println("str3的值不为空")
//输出的结果为:str3的值不为空
27.countElements()函数的使用:
let 世界杯 =
"2014世界杯4强:巴西、德国、阿根廷、荷兰"
println("世界杯 has
\(countElements(世界杯)) 个字符")
//输出结果所示,这个函数统计字符是把汉字及字符等都当作一个字符来计算。
28.hasPrefix和hasSuffix方法的使用:
strA = "Hello"
strB = "Hello"
//-----------字符串前缀相等
hasPrefix---------
strA.hasPrefix("H"){
& println("字符串前缀-相等")
& println("字符串前缀-不相等")
//-----------字符串后缀相等
hasSuffix---------
strA.hasSuffix("o"){
& println("字符串后缀-相等")
& println("字符串后缀-不相等")
//输出结果为:字符串前缀-相等
字符串后缀-相等
29.uppercaseString和lowercaseString属性的使用:
strA = "Hello"
//-----------字符串全部大写转换
strB = strA.uppercaseString //uppercaseString 字符串大写转换
//------------字符串全部小写转换
var strC =
strA.lowercaseString //lowercaseString 字符串转换小写
println(strC)
//输出结果为:HELLO
30.在Swift中不论是String类型还是Character类型都是用双引号括起来。
31.属性中的占位符(Placeholder)属性:在还没有编辑的时候显示的内容。
32.属性中的清除按钮(Clear
Button)属性:设置为Appears while
editing,则在输入内容后,会显示全部删除内容的图标,就不用一个一个删除了。
33.窗口里的控件不居中,消失,乱,不能编排,把Use Auto
Layout的勾去掉即可。
34.断点调试最常见的3种调试支持:单步调试、步入调试和步出调试。
单步调试:当程序执行到指定断点之后,单步调试可控制程序代码每次只执行一行——即用户每单击该按钮一次,程序向下执行一行代码。如果调用了方法,程序不会跟踪方法的执行代码。
步入调试(Step
into):当进行单步调试时,如果某行代码调用了一个方法,而且开发者希望跟踪该方法的执行细节,则可使用步入调试来跟踪该方法的执行。
步出调试(Step
out):当使用步入调试跟踪某个方法之后,如果开发者希望快速结束该方法,并返回该方法的调用环境,即可单击该步出按钮。
35.元组的格式:
var health = (182, 78,
"良好”)//(.0 182, .1 78, .2 "良好")
var score: (Int, Int,
String, Double)
score = (98, 89, "及格",
20.4)//(.0 98, .1 89, .2 "及格", .3 20.4)
var test: (Int, (Int,
test = (20, (15,
"Swift”))//(.0 20, (.0 15, .1 "Swift"))
println("\(test.1.1)”)//“Swift”
var (height, weight,
status) = health
println("身高:\(height)、体重:\(weight)、身体状态:\(status)”)//"身高:182、体重:78、身体状态:良好"
let (swift, oc, lua, _)
println("swift成绩:\(swift)、OC成绩:\(oc)、Lua成绩:\(lua)”)//"swift成绩:98、OC成绩:89、Lua成绩:及格"
36.可选绑定:
var str : String! =
"fkit.org"
如果可选变量str有值,将值赋值给tmp变量。
if var tmp =
& println("str的值为:\(tmp)")
& println("str的值为nil,不能解析!")
//输出结果为:str的值为:fkit.org
37.隐式可选类型主要用于定义那些被赋值之后不会重新变为nil的变量。如果一个变量在其生存期间内可能重新变为nil,那么应该使用普通可选类型来定义该变量。
var s2 : String! =
“crazyit.org”
//s2就是隐式可选类型的变量,因此程序可以直接将s2赋值给String类型的变量。
38.不断补充中。。。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。如何在 Swift 中进行错误处理 - 推酷
如何在 Swift 中进行错误处理
今天的文章讲解如何在 Swift 中进行错误处理。
说实话,为了配合这个冬季:snowflake:?,我取了一个有趣的文章标题。
译者注:原文标题为 Let it throw, Let it throw! 是模仿冰雪奇缘的主题曲 Let it go ,并且文章的副标题也在模仿冰雪奇缘的经典台词。
Objective-C 以及对应的 NSError
还记得 Objective-C 吗?那时,官方的方法是通过传入一个 NSError* 的引用进行错误处理。
BOOL ok = [string writeToFile:path
atomically:YES
encoding:NSUTF8StringEncoding
error:&error];
if (!ok) {
NSLog(@“发生了一个错误: %@&, error);
那简直是太痛苦了。以至于许多人不想甚至是懒得去检查错误,只是简单的在那里传一个 NULL 。这是很不负责且不安全的行为。
抛出一个错误
Swift 2.0 以后,苹果决定采用一种不同的方式进行错误处理:使用 throw 。
使用 throw 非常的简单:
如果你想创建一个可能出错的函数,用 throws 标记在它的签名处;
如果需要的话,可以在函数中使用 throw someError ;
在调用的地方,你必须明确的在能抛出错误的方法的前面使用 try ;
可以使用 do { … } catch { … } 这样的结构用来捕获并处理错误。
看起来像这样:
// 定义一个可以抛错误的方法…func someFunctionWhichCanFail(param: Int) throws -& String {
if (param & 0) { return &somestring&
else { throw NSError(domain: &MyDomain&, code: 500, userInfo: nil)
}}// … 然后调用这个方法do {
let result: String = try someFunctionWhichCanFail(-2)
print(&success! \(result)&)}catch {
print(&Oops: \(error)&)}
错误再也阻挡不了我了
你可以看到 someFunctionWitchCanFail 返回了一个普通的 String ,当一切正常的情况下, String 也是其返回值的类型。先考虑最简单的情况(在 do { … } 中的),“通常情况下”可以很方便的调用这个函数去处理没有错误发生的情况。
唯一的这些方法可能会出错的提醒就是 try 关键字,编译器强制让你把 try 添加到方法调用的位置的前面,否则就像是调用一个无抛出错误的方法。然后,只需要在一个单独的地方(在 catch 里)写错误处理的代码。
要注意的是你可以在 do 代码段中写多于一行的代码(并且 try 可以调用不止一个抛错误的方法)。如果一切顺利的话,将会像预期的那样执行那些方法,但是一旦方法出错就会跳出 do 代码段,进入 catch 处。对于那些有很多潜在错误的大段代码来说,你可以在一个单一的错误路径中处理所有的错误,这也是非常方便的。
NSError 有点挫了
OK,在这个例子下,我们仍然得用 NSError 处理错误,这有点痛苦。用 == 来比较域和错误代码,以及制作一个域和常量代码的列表,只是为了知道我们得到了什么错误以及如何正确的处理。。。哎哟。
但是我们可以解决这个问题!如果用
这篇文章里的知识:用 enum 替代 errors,将会怎样?
好吧,有一个好消息,那就是苹果提供了新的错误处理模式。事实上,当一个函数抛出错误时,它可以抛出任何遵从 ErrorType 的错误。 NSError 是其中的类型之一,但是你也可以自己搞一个,苹果也推荐这么做。
最适合 ErrorType 类型的就是 enum 了,如果有需要的话,甚至二者之间可以有关联值。比如:
enum KristoffError : ErrorType {
case ClumsyWayHeWalks
case GrumpyWayHeTalks
case PearShapedSquareShapedWeirdnessOfHisFeet
case NotWashedSince(days: Int)}
现在你就可以在一个函数里使用 throw KristoffError.NotWashedSince(days: 3) 来抛出错误,然后在调用的地方使用 catch KristoffError.NotWashedSince(let days) 来处理这些错误:
func loveKristoff() throws -& Void {
guard daysSinceLastShower == 0 else { throw KristoffError.NotWashedSince(days: daysSinceLastShower)
try loveKristoff()}catch KristoffError.NotWashedSince(let days) {
print(&Ewww, he hasn't had a shower since \(days) days!&)}catch {
// 所有其他类型的错误
print(&I prefer we stay friends&)}
相比此前,这种方式更容易的捕获错误!
这也让错误拥有了清晰的名字、常量以及关联值。再也没有复杂的 userInfo 了,在 enum 中你可以清楚地看到值的关联,就像如上例子中的 days ,并且它只对特定的类型有效(不会对 ClumsyWayHeWalks 中的 days 关联值有效)。
根本拿不回来
当你调用一个正在抛出错误的函数时,抛出的错误就会被调用函数中的 do...catch 捕获。但是如果错误没有被捕获,它就会被传递到上一层。比如:
func doFail() throws -& Void { throw … }func test() {
do { try doTheActualCall()
} catch { print(&Oops&)
}}func doTheActualCall() throws {
try doFail()}
这里,当 doFail 被调用时,潜在的错误没有被 doTheActualCall 捕获(没有 do...catch 来捕获它),所以它就被传递到 test() 函数。由于 doTheActualCall 没有捕获任何错误,所以它必须被标记为 throws :即使它不能通过自己抛出错误,但仍能传递。它自己不能处理错误,必须抛出到更高层。
另一方面, test() 在内部捕获所有的错误,所以,即使它调用一个抛出函数( try doTheActualCall() ),这个函数抛出的所有的错误都会在 do...catch 块中被捕获。函数 test() 本身不抛出错误,所以调用者也不要知道其内部行为。
隐藏,不要让他们知道
你现在可能很好奇,如何知道方法到底抛出哪种错误。的确,被 throws 标记的函数到底能抛出哪种 ErrorType ?它能抛出 KristoffErrors 、 JSONErrors 或者其他类型吗?我到底需要捕获哪种呢?
好吧,这的确是个问题。目前,由于一些二进制接口以及弹性问题(resilience concerns),这还是不可能的。唯一的方式就是用你代码的文档。
但这也是一件好事。比如说,假如你用了两个库, MyLibA 中函数 funcA 会抛出 MyLibAError 错误, MyLibB 中函数 funcB 会抛出 MyLibBError 错误。
然后你可能想创建你自己的库 MyLibC ,封装之前的两个库,用函数 funcC() 调用 MyLibA.funcA() 和 MyLibB.funcB() 。所以,函数 funcC 的结果可能会抛出 MyLibAError 或者 MyLibBError 。而且,如果你添加了另一个抽象层,这就变得很糟糕了,会有更多的错误类型被抛出。如果我不得不把它们都列出来,并且调用的地方需要把它们全部捕获,这将会造成一堆冗长的签名和 catch 代码。
别让他们进来,别让他们看见
基于上面的原因,也为了防止你的内部错误超出你的库的作用域,以及为了限制那些必须由用户处理的错误类型的数量,我建议把错误类型的作用域限制在每个抽象层次。
在如上的例子中,你应该抛出 MyLibCErrors 取而代之,而不是让 funcC 直接传递 MyLibAErrors 和 MyLibBErrors 。我的建议有如下的两个原因,都是和抽象相关的:
你的用户不应该需要知道你在内部使用哪个库。如果将来的某天,你决定改变你的实现:使用 SomeOtherPopularLibA 替代 MyLibA ,显然这个库不会抛出相同的错误,你自己的 MyLibC 框架的调用者不需要知道或关心。这就是抽象应该干的事。
调用者不应该需要处理所有的错误。当然你可以捕获那些错误中的一些并且在内部处理:把 MyLibA 抛出的所有错误都暴露给用户是没有意义的,比如一个 FrameworkConfigurationError 错误表明你误用了 MyLibA 框架并且忘了调用它的 setup() 方法,或者是任何不应该由用户做的事情,因为用户根本无能为力。这种错误是你的错误,而不是别人的。
所以,取而代之,你的 funcC 应该很可能捕获所有 MyLibAErrors 和 MyLibBErrors ,封装它们为 MyLibCErrors 替代。这样的话,你的框架的使用者不需要知道你在内部使用了什么。你可以在任何时候改变你的内部实现和使用的库,并且你只需要给用户暴露那些他们可能需要关注的错误。
译者注:原标题为 We finish each others sandwiches ,是在模仿冰雪奇缘中王子和公主的对话,表示和其他博主以及读者的一种亲近的关系。
throw 话题和 Swift 2.0 的错误处理模型还有很多东西可讲,我本可以讲一些关于 try? 和 try! ,或者关于高阶函数中的 rethrows 关键字。
这里没有时间对每个话题面面俱到了,那会使得我的文章非常长。但是别人有趣的文章将会帮你探索 Swift 错误处理的世界,包括但不限于:
by Rob Napier
by Little Bites of Cocoa
, by Brad Larson
… (别犹豫了,快去评论区分享更多链接吧!)
更多关于在 Objective-C 中错误处理的信息,可以参考这篇文章:
。今天的文章是关于 Swift 中的新方式的,所以别在旧事物上花费太多的时间。
尽管它叫 throw ,但是 throw 不是像 Java 或者 C++ 甚至 OC 中的 throw exception。但是使用的方式非常相似,苹果决定保留相同的措辞,所以习惯于 exceptions 的人会感到非常自然。
这是编译器强制的,其目的是让你意识到这个函数可能出错,你必须处理潜在的错误。
Swift 2.0 还不支持 typed throws,但是
有一个关于添加这个特性的讨论,Chris Lattner 解释了 Swift 2 不支持的原因,以及为什么我们需要 Swift 3.0 的弹性模型以获得这个特性。
好了,我保证这是我最后一次可耻使用 Frozen (《冰雪奇缘》) 标题了。
本文由 SwiftGG 翻译组翻译,已经获得作者翻译授权,最新文章请访问http://swift.gg。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致

我要回帖

更多关于 xcode7 编译swift错误 的文章

 

随机推荐