swift - 尝试以正确的方式处理错误和可选项
问题描述
我正在尝试使用 SwiftSoup 来抓取一些 HTML。这个示例基于 SwiftSoup github 文档,运行良好……</p>
func scrape() throws {
do {
let htmlFromSomeSource = "<html><body><p class="nerp">HerpDerp</p><p class="narf">HoopDoop</p>"
let doc = try! SwiftSoup.parse(htmlFromSomeSource)
let tag = try! doc.select("p").first()!
let tagClass = try! tag.attr("class")
} catch {
print("oh dang")
throw Abort(.notFound)
}
print(tagClass)
}
…直到我弄乱了选择器或属性目标,此时由于隐式解包的选项(我认为这只是让更聪明的人开始的快速而肮脏的代码),一切都崩溃了。那 do/catch 似乎根本没有帮助。
那么正确的方法是什么?这编译...
print("is there a doc?")
guard let doc = try? SwiftSoup.parse(response.body.description) else {
print("no doc")
throw Abort(.notFound)
}
print("should halt because there's no img")
guard let tag = try? doc.select("img").first()! else {
print("no paragraph tag")
throw Abort(.notFound)
}
print("should halt because there's no src")
guard let tagClass = try? tag.attr("src") else {
print("no src")
throw Abort(.notFound)
}
...但是如果我弄乱了选择器或属性,它会再次崩溃,“在展开可选值时意外发现 nil”(在“是否有文档?”之后)。我认为当遇到 nil 时,guard 会停止该过程?(如果我将“try?”转换为“try”,编译器会抱怨“条件绑定的初始化程序必须具有可选类型”......)
解决方案
如果您声明该函数,因为throws
您不需要do - catch
函数内的块。只需删除块和感叹号后将try
错误传递给调用者函数。
func scrape() throws { // add a return type
let htmlFromSomeSource = "<html><body><p class="nerp">HerpDerp</p><p class="narf">HoopDoop</p>"
let doc = try SwiftSoup.parse(htmlFromSomeSource)
guard let tag = try doc.select("p").first() else { throw Abort(.notFound) }
let tagClass = try tag.attr("class")
// return something
}
推荐阅读
- jenkins - 在另一个 jenkinsfile 中运行外部 jenkinsfile
- python - python raw_input、input等多行方法读取std输入失败
- excel - VBA function that will look in cell comment that have multiple lines for a specific line
- sonarqube - SonarCloud 代码覆盖率在 GitHub Actions 构建中保持为 0.0
- javascript - JS 递归地映射对象名称
- vbscript - 如何获取非内置对象 (API) 的参考
- android - 发布后是否可以更改 Android targetSdkVersion?
- html - 在由 div 组成的类似表格的结构中将列粘贴到左侧和顶部
- angular - 从Angular中的父路由组件向当前子路由添加查询参数
- sql - 有没有办法计算两次相同的日期列?