

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Difficulty: 3
click for more info
Not enough gems
Cost: 6 gems
1: Functions
incomplete
2: Multiple Parameters
incomplete
3: Unit Test Lessons
incomplete
4: Declaration Syntax
incomplete
5: Passing Variables by Value
incomplete
6: Ignoring Return Values
incomplete
7: Named Return Values
incomplete
8: The Benefits of Named Returns
incomplete
9: Explicit Returns
incomplete
10: Early Returns
incomplete
11: Functions As Values
incomplete
12: Anonymous Functions
incomplete
13: Defer
incomplete
14: Block Scope
incomplete
15: Processing Orders
incomplete
16: Closures
incomplete
17: Currying
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
Go supports the ability to return early from a function. This is a powerful feature that can clean up code, especially when used as guard clauses.
Guard Clauses leverage the ability to return early from a function (or continue through a loop) to make nested conditionals one-dimensional. Instead of using if/else chains, we just return early from the function at the end of each conditional block.
func divide(dividend, divisor int) (int, error) {
if divisor == 0 {
return 0, errors.New("can't divide by zero")
}
return dividend/divisor, nil
}
Error handling in Go naturally encourages developers to make use of guard clauses and early returns. JavaScript can use the same pattern, but many real-world JS codebases still lean heavily on nested conditionals. When I started writing more JavaScript, I noticed how much more deeply nested many of those functions were compared to their Go equivalents.
Let's take a look at an exaggerated example of nested conditional logic:
func getInsuranceAmount(status insuranceStatus) int {
amount := 0
if !status.hasInsurance(){
amount = 1
} else {
if status.isTotaled(){
amount = 10000
} else {
if status.isDented(){
amount = 160
if status.isBigDent(){
amount = 270
}
} else {
amount = 0
}
}
}
return amount
}
This could be written with guard clauses instead:
func getInsuranceAmount(status insuranceStatus) int {
if !status.hasInsurance(){
return 1
}
if status.isTotaled(){
return 10000
}
if !status.isDented(){
return 0
}
if status.isBigDent(){
return 270
}
return 160
}
The example above is much easier to read and understand. When writing code, it's important to try to reduce the cognitive load on the reader by reducing the number of entities they need to think about at any given time.
In the first example, if the developer is trying to figure out when 270 is returned, they need to think about each branch in the logic tree and try to remember which cases matter and which cases don't. With the one-dimensional structure offered by guard clauses, it's as simple as stepping through each case in order.