returns in GoOctober 18, 2021
Consider the following Go code, which checks if the file
~/.config/config_dir/config exists or not (on Unix-like systems):
package main
import (
"os"
"fmt"
"path/filepath"
"errors"
)
func configExists() (bool, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return false, fmt.Errorf("Couldn't get home directory")
}
_, err = os.Open(filepath.Join(homeDir, ".config", "config_dir", "config"))
if err == nil {
return true, nil
} else if errors.Is(err, os.ErrNotExist) {
return false, nil
} else if err != nil {
return false, err
}
}
func main() {
configExists()
}
If you haven’t realized already, this code will not compile. You will see this
compilation error: 'missing return at end of function'. The compiler doesn’t
know if this program will always return something valid—even if we can see that
it always will. If you change the last else if statement to else, however,
the compilation will go smoothly.
The Go compiler can detect many cases in which the return statement can be
omitted at the end of a function. Here are some functions I wrote while trying
to understand the compiler’s behavior—I hope you find them useful too:
package main
// The compiler seems to be smart enough to know when to force the addition
// of a return statement.
func foo() int {
i := 0
if i == 0 {
j := 9
if j == 10 {
return 9
} else { // Try removing this else! (You're in for a surprise.)
return 21
}
} else {
return 10
}
}
// This will not compile.
func BarFoo() int {
i := false
switch i {
case true:
return 12
case false:
return 13
}
}
// This, however, will compile, because of the "default" case.
func bar() int {
i := false
switch i {
case true:
return 12
case false:
return 13
default:
return 10
}
}
// This will compile, because of the infinite for loop without any break
// statement(s).
func fooBar() int {
for {
}
}
// This will compile too!
func barFoo() int {
panic("barFoo is panicking!")
}
// This will not compile, even though it's obvious to us that something valid is
// always returned.
func FooBar() int {
i := 0
if i == 0 {
return 1
} else if i != 0 {
return 90
}
}
func main() {
}