Swift的官方网站上的About页面列出了三个关键字:
- 安全(Safe):为了最大限度地减少开发人员的错误;
- 迅速(Fast):执行的速度要快;
- 表现力(Expressive):因为Swift的目标是尽可能清晰易懂。
是什么使代码 “Swifty”? —— Safe 介绍了如何有选择地使用类型系统的各个方面和功能,以使我们的代码更易于理解和使用。
是什么使代码 “Swifty”? —— Fast 介绍了如何利用系统的一些内置方法来提示性能
Swifty Code —— Expressive
清晰明确的命名(Clear, expressive naming)
最后,让我们看一下第三个关键字——富有表现力(Expressive)。尽管很容易将表现力视为纯粹的修饰,并且涉及挑剔的方法名称,直到它们都被阅读成语法上完美的英语句子为止,但最终还是要使我们的代码清楚地传达其含义。
假设我们编写了一个当前称为getContent
的函数,该函数会为捆绑的Content
模型加载数据,然后对其进行解码:
func getContent(name: String) -> Content? {
guard let url = Bundle.main.url(
forResource: name,
withExtension: "json"
) else {
return nil
}
guard let data = try? Data(contentsOf: url) else {
return nil
}
return try? JSONDecoder().decode(Content.self, from: data)
}
同样,乍看之下,上面的功能似乎非常好。没有明显的错误,可以完成工作。但是,就表达能力而言,绝对可以改进。
首先,它的当前名称“get content”并没有真正告诉我们如何检索内容。
- 是否将其简单地创建为新实例?
- 是否将其通过网络加载或其他?
- 此外,万一发生错误,它仅返回
nil
的事实会使万一发生任何故障而使调试变得更加困难——因为我们将无法得知实际出了什么问题。
因此,让我们先将功能重命名为loadBundledContent
(以明确我们正在从应用程序包中加载内容),看看我们是否可以改善这些问题。我们还将为它提供一个外部参数标签,使它读起来更好一些,最后,使它通过抛出它来报告遇到的任何错误,如下所示:
func loadBundledContent(named name: String) throws -> Content {
guard let url = Bundle.main.url(
forResource: name,
withExtension: "json"
) else {
throw Content.Error.missing
}
guard let data = try? Data(contentsOf: url) else {
throw Content.Error.missing
}
do {
return try JSONDecoder().decode(Content.self, from: data)
} catch {
throw Content.Error.decodingFailed(error)
}
}
有关上述设计抛出API的方式的更多信息,请查看Swift: 提供统一的错误API。
更改前后,调用的对比如下:
代码语言:javascript复制// Before
let content = getContent(name: "Onboarding")
// After
let content = try loadBundledContent(named: "Onboarding")
重要的是不要过分依赖我们命名的函数和类型(毕竟,通常这取决于口味和偏好),但如果我们能够找到更清晰地传达每个API的功能的方法,那巨大的胜利——因为它不仅使新开发人员更容易熟悉我们的代码库,而且通常还可以使我们的代码更加愉快的长期使用。
结语
在我看来,编写“ Swifty”代码不是要使用尽可能多的语言功能,也不是通过部署Swift的最高级功能来解决简单的问题来使我们的代码不必要地变得复杂——而是要调整我们设计和表达代码的方式,并它具有Swift的核心原则集的各种API。
通过充分利用标准库,并通过表达性命名和API设计传达我们的代码意图,使我们的代码使用Swift的类型系统来确保正确性并使其功能更加清晰,我们常常最终得到了更好的代码匹配Swift本身,这难道不是编写“ Swifty Code”要讲述的吗?
文章来自 John Sundell的What makes code “Swifty”?中关于Expressive的内容
是什么使代码 “Swifty”? —— Safe 介绍了如何有选择地使用类型系统的各个方面和功能,以使我们的代码更易于理解和使用。
是什么使代码 “Swifty”? —— Fast 介绍了如何利用系统的一些内置方法来提示性能