黄金路径/Golden Path
When coding with conditionals, the left-hand margin of the code should be the "golden" or "happy" path. That is, don't nest if
statements. Multiple return statements are OK. The guard
statement is built for this.
当使用条件语句编码时,代码的左边距应该是“黄金”或“快乐”的路径。换句话说,不要嵌套 if
语句。多个返回语句是可以的。guard
语句就是因为避免这个问题而生的。
推荐(Preferred):
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
guard let context = context else {
throw FFTError.noContext
}
guard let inputData = inputData else {
throw FFTError.noInputData
}
// use context and input to compute the frequencies
return frequencies
}
不推荐(Not Preferred):
func computeFFT(context: Context?, inputData: InputData?) throws -> Frequencies {
if let context = context {
if let inputData = inputData {
// use context and input to compute the frequencies
return frequencies
} else {
throw FFTError.noInputData
}
} else {
throw FFTError.noContext
}
}
When multiple optionals are unwrapped either with guard
or if let
, minimize nesting by using the compound version when possible. In the compound version, place the guard
on its own line, then indent each condition on its own line. The else
clause is indented to match the conditions and the code is indented one additional level, as shown below. Example:
用 guard
或 if let
解包多个可选值时,在条件允许的状态下,尽量使用混合的方式来简化嵌套。在混合的方式中,将 guard
关键字放在句子的最开始处,并缩进与此相关的条件分支。else
与 guard
字句的缩进匹配。就像下面的示例一样:
推荐(Preferred):
guard
let number1 = number1,
let number2 = number2,
let number3 = number3
else {
fatalError("impossible")
}
// do something with numbers
不推荐(Not Preferred):
if let number1 = number1 {
if let number2 = number2 {
if let number3 = number3 {
// do something with numbers
} else {
fatalError("impossible")
}
} else {
fatalError("impossible")
}
} else {
fatalError("impossible")
}
失败防护/Failing Guards
Guard statements are required to exit in some way. Generally, this should be simple one line statement such as return
, throw
, break
, continue
, and fatalError()
. Large code blocks should be avoided. If cleanup code is required for multiple exit points, consider using a defer
block to avoid cleanup code duplication.
在某些退出的场景下,防护语句是必不可少的。一般来说,它应该是一行简洁的语句,比如:return
、throw
、break
、continue
和 fatalError()
。应该避免大量的代码块。如果与清理相关的代码被用在多个退出点,则可以考虑用 defer
块来避免代码的重复。