1

When a function returns more than one variable in Golang, what's the scope of the variables? In the code attached, I can't figure out the scope of b.

package main

import (
    "fmt"
)

func addMulti(x, y int) (int, int) {
    return (x + y), (x * y)
}

func main() {
    //what is the scope of the b variable here?
    a, b := addMulti(1, 2)

    fmt.Printf("%d %d\n", a, b)

    //what is the scope of the b variable here?
    c, b := addMulti(3, 4)

    fmt.Printf("%d %d\n", c, b)

}   
1
  • The variable will live until the last line of main; however, the value of 'b' will be mutated on your second call to addMulti(). This is typical of any programming language, and it has nothing to do with multiple returns. Commented Jan 21, 2015 at 16:19

4 Answers 4

10

We're not talking about the scope of the return value of a function but rather the scope of the variable you assign the return value to.

The scope of the variable b in your case is the function body, from the point at which you declare it.

At first you do it at this line:

a, b := addMulti(1, 2)

But then you use another Short Variable declaration at this line:

c, b := addMulti(3, 4)

which - since b is already declared - just assigns a new value to it. b will be in scope until the end of your main() function. Quoting from the Go Language Specification:

Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block with the same type, and at least one of the non-blank variables is new. As a consequence, redeclaration can only appear in a multi-variable short declaration. Redeclaration does not introduce a new variable; it just assigns a new value to the original.

Sign up to request clarification or add additional context in comments.

5 Comments

So could we change the code of the second call to addMulti(3, 4) so that it assigns the return values to a, b?
@G4143 What and why do you want to change it? To keep the previous value of b? If so then simply use a new variable, for example: c, d := addMulti(3, 4)
Probably worth noting that this has nothing to do with multiple return values--it could be as easily demonstrated with b := 4 followed by b = 5. You're just mutating the value contained in the variable.
@weberc2 Yes, this is true, but there is one important difference: with multiple return values the short variable declaration := could be used which might be confusing what happens to the (existing) variable, while if there is only one return value, at the second call you can only use = to store its return value into an existing variable which is clear in that it is just an assignment (and not a (re)declaration).
@icza Ah, I understand. Yeah, that is important. Maybe you could just mention that there is no difference despite the different operator.
0

It's a normal variable inside a block. From the spec:

The scope of a constant or variable identifier declared inside a function begins at the end of the ConstSpec or VarSpec (ShortVarDecl for short variable declarations) and ends at the end of the innermost containing block.

In the second call, you're just reassigning the value of the same b variable. Its scope is the same.

Comments

0

The scope of b variable is main.main(). In second assignment c, b := addMulti(3, 4) you introduce new variable c, and assign variable b introduced in first assignment. If you change second assignment to be a, b := addMulti(3, 4) same as first it want not to compile.

Comments

-1

If that's the case, try the following code:

func makeRequest(uri string, payload string) {
    var resp http.Response
    var err error

    if payload == "" {
        resp, err := http.Get(uri)
    }
    if err != nil {
        return
    }

    bytes, err := io.ReadAll(resp.Body)
    fmt.Println(bytes)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.