3 ms·
Wait... x, err := strconv.Atoi("123") if err != nil { panic(err) } y, err := strconv.Atoi("1234") fmt.Println("result:", x, y) > this also compi
by Pxtl 1y ago
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?
- JamesSwift 1y agoAs 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)
- Pxtl 1y ago... I thought Go's whole deal was that you give up the expressiveness and power of overdesigned languages for simple, clean, "only one way to do it" semantics. That "special cases reassignment" where ':=' is sometimes a shadowing declaration and sometimes a reassignment sounds like the opposite of that.
- homebrewer 1y agoThe language is full of gotchas like that, you're expected to use the tooling to guardrail yourself, because having a proper type system or coherent syntax is "too complicated" (while learning dozens of patterns and weird tricks apparently isn't). go vet and this massive collection of linters bundled into a single binary are very popular: https://golangci-lint.run https://golangci-lint.run linters will warn you of accidental shadowing, among many other things.
- masklinn 1y ago> That "special cases reassignment" where ':=' is sometimes a shadowing declaration and sometimes a reassignment sounds like the opposite of that. FWIW it is never a shadowing declaration. It is at least one non-shadowing declaration plus any number of reassignments. The fun part is the tendency to keep reassigning to `err` makes the unused variable largely useless, so it’s just there to be a pain in the ass, and your need a separate lint anyway.
- kbolino 1y agoIt'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.
- Pxtl 1y agoThanks, I hate it.
- recursivecaveat 1y agoThis, along with stuff like implicit access modifiers based on case, nil interface confusion, named or multiple return values, channel lockups, and `append` oddities make it ring a bit hollow when people complain that no-one could be expected to google once and learn what snippet a `?` operator expands to. Like I don't even necessarily hate all these things, just please don't pretend it's the heart and soul of minimalism or approachable predictability.
- nasretdinov 1y agoYeah, people complain about `if err != nil`, but the real issues are tricky rules around variable shadowing, lack of nil safety and immutability, cgo, defer semantics, etc
- School-Cotton 1y agoOh 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.