Golang Grammar Quiz vol.3: Named Return Parameters

Golang Grammar Quiz vol.3: Named Return Parameters

Hello! Welcome to the third post in the Golang Grammar Quiz series, where we'll be covering some questions about named return parameters. This content is based on Jon Bodner's presentation at GopherCon 2018, which you can watch here.

As Jon Bodner explains in the presentation, named return parameters are one of the iconic features of Go.

They allow you to declare return parameters in the function signature and use them in the function body, and return them by simply calling return without any arguments, like this:

package main

import "fmt"

func double(n int) (res int) {
    res = n * 2
    return
}

func main() {
    n := 10
    doubled := double(n)
    fmt.Println(doubled)
}

Question 1

With named return parameters, you can return a value by just calling return without any arguments. But what happens if you call return with a value?

package main

import "fmt"

func foo(n int) (res int) {
    res = n * 2
    return 5
}

func main() {
    n := 10
    res := foo(n)
    fmt.Println(res)
}

What do you think the output of this code is?

A. 5

B. 20

C. Panics

D. Doesn't compile

Answer and Explanation

The correct answer is A. 5. The value in the return statement takes precedence.

Question 2

Now, what does this code with multiple defer statements return?

package main

import "fmt"

func bar(n int) (res int) {
    defer func() {
        res = res + 1
    }()
    defer func() {
        res = res * 3
    }()
    res = n * 2
    return 20
}

func main() {
    res := bar(5)
    fmt.Println(res)
}

A. 20

B. 31

C. 33

D. 61

Answer and Explanation

The correct answer is D. 61.

A couple of things to note here:

First, the defer statements are executed in reverse order just before the function exits. So, the second defer statement is executed first, followed by the first defer statement.

Second, when you call return with a value, like return 20 at the end of bar(), the named return parameter is set to that value, making the value of res equal to 20.

What happens next is that the defer statements are executed in the reverse order, therefore the value of res is multiplied by 3 first, and then 1 is added to it.

Next, the defer statements are executed in reverse order, so the value of res is first multiplied by 3, then 1 is added to it.

This is how the final value of res becomes 61.

Wrap up

We've covered some questions about named return parameters in Go in this post.

Remember that the value in the return statement takes precedence when you call return with a value in a function with named return parameters.

Additionally, if you modify the named return parameter in a defer statement, the value will be changed before the function exits.

I hope this quiz was helpful and intuitive for you. If you have any questions or feedback, please feel free to leave a comment below. Thank you for reading!