iTranslated by AI
Go Quiz: Understanding Named Return Values
This article is for Day 23 of the DeNA 20 New Grad Advent Calendar 2020.
I'll try my hand at creating a Go quiz, which seems to be a popular trend lately!
Question
What will be the output of the following code?
package main
import "fmt"
func main() {
run()
}
func run() (err error) {
defer func() {
if err != nil {
fmt.Println(err)
}
}()
if err := fmt.Errorf("Error caught!"); err != nil {
return
}
return
}
- Compilation error
- "Error caught!" is printed
- Nothing is printed
Answer and Explanation
Answer
The answer is 1.
It results in a compilation error.
Explanation
Regarding this matter, the Go spec contains the following description:
Implementation restriction: A compiler may disallow an empty expression list in a "return" statement if a different entity (constant, type, or variable) with the same name as a result parameter is in scope at the place of the return.
https://golang.org/ref/spec#Return_statements
If you declare a variable, constant, or type with the same name as a Named return value in a different scope within a function and then perform an empty return within that scope, the compiler throws an error because it's unclear which one should be prioritized (the one declared in the function's scope or the one in the nested scope).
Indeed, making the language specification prioritize one over the other would likely cause confusion, so it seems more helpful to make it a compilation error.
In this case, if you explicitly specify the value to return as follows, the code will compile and output "Error caught!".
if err := fmt.Errorf("Error caught!"); err != nil {
return err
}
(By the way, the defer was a distraction meant to mislead you.)
Extra Question
Slightly off-topic from the Named return values discussion, what will be the result of executing the following?
package main
import "fmt"
func main() {
run()
}
func run() error {
var err error
defer func() {
if err != nil {
fmt.Println("Error caught!")
}
}()
if err := fmt.Errorf("hoge error"); err != nil {
return err
}
return nil
}
- Compilation error
- "Error caught!" is printed
- Nothing is printed
Extra Answer and Explanation
Answer
The answer is 3. Nothing is printed.
Explanation
The err inside the defer statement refers to the err from var err error, so the err defined in the if statement's scope is unrelated. Therefore, nothing is printed.
This is an extra question without any particular tricks, but it's something we might accidentally implement assuming "Error caught!" would be printed, so I want to be careful.
Finally
The DeNA Official X (Twitter) Account @DeNAxTech shares this Advent Calendar, DeNA's technical articles, and presentation materials from events. Please feel free to follow if you'd like!
Discussion