kodecocodes / swift-style-guide

The official Swift style guide for Kodeco.
Other
13.09k stars 2.15k forks source link

Guard #111

Closed ghost closed 8 years ago

ghost commented 9 years ago

Hello!

Can we get some clarity around when guard should be preferred over if let binding?

I appreciate Swift 2.0 will (is?) only being released to the general public today, but I'm getting a lot of questions from the iOS team around this and would like it documented in the style guide so there's no ambiguity.

jackwu95 commented 9 years ago

I think that since we already have the Golden Path rule, guard should be always the preferred way of early-exiting a function.

mattgabor commented 8 years ago

If guards are Swift 2's replacement to if let, shouldn't the optionals section be updated to reflect this? Correct me if I'm wrong, also I'm not sure what you mean by the Golden Path rule?

Lweek commented 8 years ago

@mattgabor It is not replacement, it is supplement. It give perfect sense use both. It is like do while and while. Personally I understand guard like input condition check while if let helps me check class type or unwrap values returned from other functions (e.g. methods) called inside my function.

mattgabor commented 8 years ago

@Lweek thanks for the clarification, that makes sense. I still think it should be included in the style guide, unless it's not something used on the website.

mitchellporter commented 8 years ago

With guard, if the value ends up being nil it forces you to return and exit out of the function. Where with if let if the value ends up being nil you can still keep moving along in the function.

I'll use guard when there's absolutely no point in continuing on if the specific value is nil, and I'll use if let when I can still continue on with the function regardless if the value is nil or not.

ghost commented 8 years ago

@mitchellporter This isn't strictly true. You can also use continue and break with guard, it's not just limited to return, which means it can be used beyond just returning from the current method.

guard also requires a different mindset on how you structure your code. It's a great alternative to if-let and indentation hell, but it does require some extra thought on the part of the developer.

mitchellporter commented 8 years ago

@micpringle You're right that it's not strictly true, but to be fair unless you're in a loop you can't even use continue or break, which leaves fallthrough or return, and fallthrough's for switch statements, which means you end up with having to use return and exiting the function.

I guess I was assuming a scenario where you're using guard and it's not inside a loop :)

gregheo commented 8 years ago

I think the general explanation is "it must exit the current scope" which includes my favourite way to do that: fatalError() ;]

I don't know of a concise way to word this, but if the current structure of the code is an if-let with lots of code inside and nothing outside, then that should use guard.

Perhaps as Jack mentioned, a simple "guard rather than if-let is the preferred syntax if you need to exit early" is enough?

ghost commented 8 years ago

Don't forget that guard can, and should be used in cahoots with defer, meaning you can guarantee execution of certain parts of code even when using return.

Like I said above, and just like with a lot of Swift, using guard simply requires a different mindset.

There are obviously cases where if-let would be preferred over guard, but I see those as the exception rather than the rule.

mitchellporter commented 8 years ago

Perhaps as Jack mentioned, a simple "guard rather than if-let is the preferred syntax if you need to exit early" is enough?

@gregheo Yep.

using guard simply requires a different mindset.

@micpringle I keep reminding myself of this every few weeks while working with Swift. Sometimes I notice myself subconsciously wanting to bend Swift to meet my Objective-C way of thinking, if that makes sense.

Thank you both for the clarification on everything.

JRG-Developer commented 8 years ago

I think that since we already have the Golden Path rule, guard should be always the preferred way of early-exiting a function.

:+1: Yep, respect the Golden Path. :]

If you use if let instead, it promotes deep(er) code nesting, which is harder to read.

agordeev commented 8 years ago

I think that using guard should be included into this style guide. Can someone write about it under Optionals section? I see so few developers using this really helpful feature.

rayfix commented 8 years ago

I am going to include a section on the happy path and guard in an upcoming update. (Not sure if it will be in the optionals section or not.)