可选类型解包: if 和 guard

 一般来说,我们会优先使用所谓的"early return"策略来避免if表达式中的多层嵌套的代码。

在这种情况下使用guard语句能够有效地提升代码的可读性。

// PREFERRED

func eatDoughnut(atIndex index: Int) {

guard index >= 0 && index < doughnutselse{

// return early because the index is out of bounds

return

}

let doughnut = doughnuts[index]

eat(doughnut)

}

// NOT PREFERRED

func eatDoughnuts(atIndex index: Int) {

if  index >= 0 && index < donuts.count {

let doughnut = doughnuts[index]

eat(doughnut)

}

}

在对Optional类型进行解包的时候,优先使用 guard 语句来避免if语句中较多的缩进。

// PREFERRED

guard let monkeyIsland = monkeyIsland  else{

return

}

bookVacation(onIsland: monkeyIsland)

bragAboutVacation(onIsland: monkeyIsland)

// NOT PREFERRED

if let monkeyIsland = monkeyIsland {

bookVacation(onIsland: monkeyIsland)

bragAboutVacation(onIsland: monkeyIsland)

}

// EVEN LESS PREFERRED

if monkeyIsland == nil {

return

}

bookVacation(onIsland: monkeyIsland!)

bragAboutVacation(onIsland: monkeyIsland!)

在决定是要用if表达式还是guard表达式进行Optional类型解包的时候,最重要的点就是要保证代码的可读性。很多时候要注意因时而变,因地制宜:

// an `if` statement is readable here

if  operationFailed {

return

}

// a `guard` statement is readable here

guard isSuccessful  else{

return

}

// double negative logic like this can get hard to read - i.e. don't do this

guard  !operationFailed else{

return

}


当需要进行多可能性处理的时候,应该优先使用if表达式而不是guard表达式。

// PREFERRED

if  isFriendly {

print("Hello, nice to meet you!")

}else{

print("You have the manners of a beggar.")

}

// NOT PREFERRED

guard isFriendly  else{

print("You have the manners of a beggar.")

return

}

print("Hello, nice to meet you!")


一般来说,guard应该被用于需要直接退出当前上下文的情形。而对于下面这种两个条件互不干扰的情况,应该使用两个if而不是两个guard。

if  let monkeyIsland = monkeyIsland {

bookVacation(onIsland: monkeyIsland)

}

if  let woodchuck = woodchuck where canChuckWood(woodchuck) {

woodchuck.chuckWood()

}


有时候我们会碰到要用guard语句进行多个optionals解包的情况,一般而言,对于复杂的错误处理的Optional类型需要将其拆分到多个单个表达式中。

// combined because we just return

guard let thingOne = thingOne,

let thingTwo = thingTwo,

let thingThree = thingThreeelse{

return

}

// separate statements because we handle a specific error in each case

guard let thingOne = thingOneelse{

throwError(message: "Unwrapping thingOne failed.")

}

guard let thingTwo = thingTwoelse{

throwError(message: "Unwrapping thingTwo failed.")

}

guard let thingThree = thingThreeelse{

throwError(message: "Unwrapping thingThree failed.")

}

不要将guard表达式强行缩写到一行内。

// PREFERRED

guard let thingOne = thingOneelse{

return

}

// NOT PREFERRED

guard let thingOne = thingOneelse{return}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容