Consider the following example illustrating the question (it was just built to explain the question, but I saw similar code in books as well in real projects):
package main
import (
"strconv"
"fmt"
"log"
)
func main() {
n1, err := strconv.Atoi("1")
if err != nil {
log.Panicf("%v", err)
}
n2, err := strconv.Atoi("2")
if err != nil {
log.Panicf("%v", err)
}
// err := fmt.Errorf("new error") <- line 1
// n1, err := strconv.Atoi("3") <- line 2
fmt.Printf("n1 = %d, n2 = %d\n", n1, n2)
}
The compiler doesn't complain about redefining err
, but if I uncomment <- line 1
or <- line 2
, it will complain no new variable on left side of :=
.
So, how does it work? Why the compiler happily allows to override err
in multi return statement, using :=
, but not n1
on <- line 2
example?
Better if you can point into the official reference explaining this behavior.
It is because you used Short variable declaration :=
. Quoting from the spec:
Unlike regular variable declarations, a short variable declaration may redeclare variables provided they were originally declared earlier in the same block (or the parameter lists if the block is the function body) 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.
This line:
n1, err := strconv.Atoi("1")
Is a multi-variable short declaration, and all variables on the left side are new, and so all will be declared (and return values of strconv.Atoi()
assigned).
This line:
n2, err := strconv.Atoi("2")
It is a multi-variable short declaration, and n2
is new. So it declares n2
and only assigns a new value to err
, because err
is already declared in the same block.
This line:
err := fmt.Errorf("new error") <- line 1
It is not a multi-variable short declaration. It would try to declare err
but it is already declared in the same block, therefore it is a compile-time error.
And this line:
n1, err := strconv.Atoi("3") <- line 2
It is a multi-variable short declaration, but all the variables on the left side have been previously declared in the same block, so it is also a compile-time error (it doesn't introduce any new variables on the left side).
Note that if all the variables on the left side have been previously declared, simply changing from Short variable declaration :=
to Assignment =
will make it work (assumed values on the right side are assignable to the variables on the left side).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With