命名/Naming
Descriptive and consistent naming makes software easier to read and understand. Use the Swift naming conventions described in the API Design Guidelines. Some key takeaways include:
具有描述性和一致性的命名能够让软件更易于阅读和理解。遵循 API Design Guidelines 中描述的命名规范。下面展示了一些关键点:
striving for clarity at the call site
在调用时力求意图清晰明确
prioritizing clarity over brevity
传达清晰的意图比文字的简洁更重要
using
camelCase
(notsnake_case
)使用驼峰命名法(而不是蛇形命名法)
译者注:snake case 是指使用下划线的命名方法,详情参考链接
using
UpperCamelCase
for types (and protocols),lowerCamelCase
for everything else类型(和协议)使用首字母大写,其它都是首字母小写
including all needed words while omitting needless words
包含所有需要的单词,同时省略不必要的单词
using names based on roles, not types
基于作用命名,而不是类型
sometimes compensating for weak type information
必要时,为无明确意义的类型补充额外信息
striving for fluent usage
尽量保证使用上的流畅
beginning factory methods with
make
工厂方法要以
make
开头naming methods for their side effects
根据方法的副作用进行命名
verb methods follow the -ed, -ing rule for the non-mutating version
动词方法名的不可变版本,使用动词的 -ed 或者 —ing 形式命名
noun methods follow the formX rule for the mutating version
名词方法名的可变版本,使用 formX 来命名
> 译者注: formX 中的 X 指代对应的名词,例如 `y.formUnion()` 方法,X 指代 Union。
boolean types should read like assertions
布尔类型读起来应该像断言
protocols that describe what something is should read as nouns
描述事物的 协议,读起来应该像名词
protocols that describe a capability should end in -able or -ible
描述能力 的协议,应该使用后缀 -able,ible
using terms that don't surprise experts or confuse beginners
使用术语的时候,不要让专家觉得惊讶,也不要让初学者感到困惑
generally avoiding abbreviations
通常要避免缩写
using precedent for names
命名可以遵循先例
preferring methods and properties to free functions
优先选择方法或属性,而非全局函数
译者注:free function 在这里翻译为全局函数,详情请点击这里
casing acronyms and initialisms uniformly up or down
首字母缩写的单词要根据惯例,保持全大小或者全小写的方式
giving the same base name to methods that share the same meaning
当某些方法的含义基本一致时,可以共享方法名的基础部分
avoiding overloads on return type
避免重载返回类型
choosing good parameter names that serve as documentation
选择具有说明作用的形参名,能够让文档注释质量更高
preferring to name the first parameter instead of including its name in the method name, except as mentioned under Delegates
尽量为第一个参数设置参数标签,不要将此参数标签放在方法名中,代理模式下的方法可以忽略此规定
labeling closure and tuple parameters
为闭包和元组参数设置标签
taking advantage of default parameters
用好默认参数
在文章中引用代码/Prose
When referring to methods in prose, being unambiguous is critical. To refer to a method name, use the simplest form possible.
在文章中引用方法时,含义明确是至关重要的。尽可能用最简单的形式引用方法。
Write the method name with no parameters. Example: Next, you need to call
addTarget
.
写一个不带参数的方法。例如:下一步,你需要调用方法
addTarget
。
Write the method name with argument labels. Example: Next, you need to call
addTarget(_:action:)
.
写一个带参数标签的方法。例如:下一步,你需要调用方法
addTarget(_:action:)
。
Write the full method name with argument labels and types. Example: Next, you need to call
addTarget(_: Any?, action: Selector?)
.
写一个带参数标签和参数类型的完整方法。例如:下一步, 你需要调用方法
addTarget(_: Any?, action: Selector?)
。
For the above example using UIGestureRecognizer
, 1 is unambiguous and preferred.
上面这些 UIGestureRecognizer
的例中, 1 的表述简单明了,不会造成歧义,推荐使用。
Pro Tip: You can use Xcode's jump bar to lookup methods with argument labels. If you’re particularly good at mashing lots of keys simultaneously, put the cursor in the method name and press Shift-Control-Option-Command-C (all 4 modifier keys) and Xcode will kindly put the signature on your clipboard.
小提示: 你可以使用 Xcode 的 jump bar 来查看方法的参数标签。如果你能够相对轻松的操作多个按键,那么可以尝试将光标放在方法名上,并同时按下 Shift-Control-Option-Command-C 键,此时 Xcode 会将此方法的签名复制到剪贴板上。
译者注:与复制相关的快捷操作有三种,需要注意的是在 playground 中这些方法不生效。
* command+C :Copy(光标所在位置的单词):viewDidLoad
。
* control+shift+command+C:Copy Symbol Name(光标所在位置的消息符号名称):viewDidLoad()
。
* option+control+shift+command+C:Copy Qualified Symbol Name(光标所在位置的消息符号全名,带所属类名):ViewController.viewDidLoad()
。
类前缀/Class Prefixes
Swift types are automatically namespaced by the module that contains them and you should not add a class prefix such as RW. If two names from different modules collide you can disambiguate by prefixing the type name with the module name. However, only specify the module name when there is possibility for confusion, which should be rare.
Swift 里各种类型被其所处的模块自动分配了命名空间。不应该再添加类似于 RW 的类前缀。如果不同模块间的两个类型命名冲突,可以在类型名前添加模块名来消除歧义。无论如何,仅在少数可能引起混淆的情况下添加模块名。
import SomeModule
let myClass = MyModule.UsefulClass()
代理/Delegates
When creating custom delegate methods, an unnamed first parameter should be the delegate source. (UIKit contains numerous examples of this.)
当创建自定义的代理方法时,第一个未命名的参数应该是代理源。(UIKit 包含很多类似的例子。)
推荐(Preferred):
func namePickerView(_ namePickerView: NamePickerView, didSelectName name: String)
func namePickerViewShouldReload(_ namePickerView: NamePickerView) -> Bool
不推荐(Not Preferred):
func didSelectName(namePicker: NamePickerViewController, name: String)
func namePickerShouldReload() -> Bool
使用上下文进行类型推断/Use Type Inferred Context
Use compiler inferred context to write shorter, clear code. (Also see Type Inference.)
利用编译器根据上下文进行类型推断的能力,书写更简洁明了的代码。(你也可以阅读 类型推断。)
推荐(Preferred):
let selector = #selector(viewDidLoad)
view.backgroundColor = .red
let toView = context.view(forKey: .to)
let view = UIView(frame: .zero)
不推荐(Not Preferred):
let selector = #selector(ViewController.viewDidLoad)
view.backgroundColor = UIColor.red
let toView = context.view(forKey: UITransitionContextViewKey.to)
let view = UIView(frame: CGRect.zero)
泛型/Generics
Generic type parameters should be descriptive, upper camel case names. When a type name doesn't have a meaningful relationship or role, use a traditional single uppercase letter such as T
, U
, or V
.
泛型的类型参数应该遵循大写驼峰法命名规则,并且应该具有较强的描述性。当类型参数与函数或泛型之间无明显关联时,通常使用单个大写字母来命名,例如 T
、U
或 V
。
推荐(Preferred):
struct Stack<Element> { ... }
func write<Target: OutputStream>(to target: inout Target)
func swap<T>(_ a: inout T, _ b: inout T)
不推荐(Not Preferred):
struct Stack<T> { ... }
func write<target: OutputStream>(to target: inout target)
func swap<Thing>(_ a: inout Thing, _ b: inout Thing)
语言/Language
Use US English spelling to match Apple's API.
使用美式英语拼写,和 Apple 的 API 一致。
推荐(Preferred):
let color = "red"
不推荐(Not Preferred):
let colour = "red"