logoalt Hacker News

Pxtllast Tuesday at 6:10 PM3 repliesview on HN

Wait...

  x, err := strconv.Atoi("123")
  if err != nil {
    panic(err)
  }
  y, err := strconv.Atoi("1234")
  fmt.Println("result:", x, y)
> this also compiles and runs just fine but again you would have no idea something was wrong

Okay, I don't use golang... but I thought ":=" was "single statement declare-and-assign".

Is it not redeclaring "err" in your example on line 5, and therefore the new "err" variable (that would shadow the old err variable) should be considered unused and fail with 'declared and not used: err'

Or does := just do vanilla assignment if the variable already exists?


Replies

kbolinolast Tuesday at 6:23 PM

It's trickier than that, unfortunately. There has to be at least one new variable on the left side of := but any other variables that already exist in the same scope will simply be assigned to. However, if you use := in a nested block, then the variable is redeclared and shadows the outer-scope variable.

show 1 reply
JamesSwiftlast Tuesday at 6:16 PM

As I understand it, go has some special handling for this scenario because its so prevalent which special cases reassignment. The linked article touches on it

> There are exceptions to this rule in areas with high “foot traffic”: assignments come to mind. Ironically, the ability to redeclare a variable in short variable declarations (:=) was introduced to address a problem that arose because of error handling: without redeclarations, sequences of error checks require a differently named err variable for each check (or additional separate variable declarations)

show 1 reply
umanwizardlast Thursday at 12:03 PM

Oh no, you are making the classic mistake of assuming Go’s designers did something that would make sense, rather than picking the most insane possible design in a given situation.