The weirdness is that ":=" allows redeclaration (within a scope) but only partial, whereas `var` completely forbids redeclaration.
That is:
var a, b = f()
var a, b = f() // NO
var a, b = f()
a, b := f() // NO
// note that the second declaration only partially overlaps with the first
var a, b = f()
var a, c = f() // NO
var a, b = f()
a, c := f() // yes
I think the point is to make sure you know what you are doing. That declaring a new variable should always be an intentional act, and this makes assignments to typoed variable names error rather than just creating a new variable.
You will if you ever do concurrency stuff in go. The way goroutines capture their working variables in a closure make things like `x := x` useful and clear (once you know why you do it in the first place )
if err := fn(); err != nil {
}
// the result of fn does not affect the identifier err
// in the enclosing scope
you're scoping err just to that if block. that's ... just about the most common phrase in all of Go. it won't affect any err defined prior and it won't exist outside of the if block.
You'd have to do this to make the value stick around or affect the enclosing block:
var err error
if err = fn(); err != nil {
}
// err has the result of fn here