在Swift 1.2中我有这个:
if let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt"),
data = String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding) {
for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) {
// Do something
}
} else {
println("some.txt is missing")
}
在Swift 2中,我不能再这样做,因为pathForResource
和contentsOfFile
都可以抛出,也可以返回选项。我可以解决它,但它现在看起来非常冗长:
do {
if let filePath = try NSBundle.... {
do {
if let data = try String.... {
for line in data..... {
// Do something
}
} else {
print("Nil data")
}
} catch {
print("contentsOfFile threw")
}
} else {
print("Nil pathForResource")
}
} catch {
print("pathForResource threw")
}
我希望我错过了一些东西 - 任何帮助都会受到赞赏。
答案 0 :(得分:13)
使用保护语法而不是if-let。
以下是一个示例:
do {
guard let filePath = try NSBundle .... else {
// if there is exception or there is no value
throw SomeError
}
guard let data = try String .... else {
}
} catch {
}
if-let和guard之间的区别在于未展开值的范围。如果使用if-let filePath值仅在if-let块内可用。如果使用guard filePath值可用于调用的守护进程。
这是swift book中的相关部分
一个保护语句,就像if语句一样,执行语句依赖 在表达式的布尔值上。你使用一个守卫声明 要求条件必须为true才能使代码在。之后 守卫声明将被执行。与if语句不同,是一名警卫 语句总是有一个else子句 - else`子句中的代码 如果条件不成立则执行。
答案 1 :(得分:8)
我可以说,只有上面的String初始值设定项实际上会抛出一个错误(尽管pathForResource()
可能会从返回一个可选值变为在某个时候抛出错误)。因此,以下内容应该复制您之前所做的事情:
if let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt") {
do {
let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)
for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) {
// Do something
}
} catch {
print("Couldn't load the file somehow")
}
} else {
print("some.txt is missing")
}
您的字符串不再是可选字符,因此不需要if let
。
正如mustafa指出的那样,guard
语句可用于删除成功案例中的缩进级别:
guard let filePath = NSBundle.mainBundle().pathForResource("some", ofType: "txt") else {
print("some.txt is missing")
}
do {
let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)
for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) {
// Do something
}
} catch {
print("Couldn't load the file somehow")
}
现在,如果pathForResource()
从返回可选项更改为抛出错误,则可以按顺序使用这些try语句:
do {
let filePath = try NSBundle.mainBundle().pathForResource("some", ofType: "txt")
let data = try String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)
for line in data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) {
// Do something
}
} catch {
print("some.txt is missing")
}
抛出错误的第一个语句将在那时发生,阻止执行任何过去的操作。单个catch语句足以从一系列可用的操作中获取任何内容,这使得链接它们变得容易。