-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: Go 2: prevent variable aliasing/shadowing #21114
Comments
But you could also do the mistake and write |
If declarations in inner scopes cannot shadow declarations in outer scopes then what are scopes even good for? |
What if shadowing was allowed with var but not :=? |
@cznic do you have an example showing shadowing as useful or necessary?
|
Yes, here: https://gist.github.com/posener/92a55c4cd441fc5e5e85f27bca008721#how-to-solve-this Maybe it's not the nicest way to do it, but it's the least code changing one to do. It's not necessary, but it's definitely useful. |
Shadowing is useful wherever a separate scope is useful. Just one of the endless posibilities: var i, j int
var l list
// ... do something with i
for i := 0; i < n; i++ {
var l list
// ... shadowing i and l does not destroy their values in the outer scope
j += foo(i)
}
println(i, j, list) |
I think whether or not the proposal is reasonable. btw, now "go vet" support a "-shadow" option to warn on such traps. |
go vet supported that for a long time now, but it's not accurate in terms of detection as not all shadows are wrong ,as seen by the examples above. Editors that integrate with Given the tooling support that exists around this problem, and the fact that users can make a conscious decision of when they should or should not shadow variables, I argue that this functionality is more useful than detrimental to the language, alternative solutions for "fixing" this by not having shadowing allowed resulting in more code needed to handle those cases. |
Having opened the bug I might be biased, but I disagree with this. The "more" code mentioned is a very little sacrifice, in comparison to the likelihood of introducing a tripping bug that would take hours to find and fix, due to being so intrinsic with the language. In my opinion this functionality adds little to no benefit, and adds semantic complications that are just not worth it. I don't have any data, but the number of people consciously shadowing variables are probably much fewer than those being tripped by it. In other words, I would 100% trade the "more code" for a reduced risk of introducing a bug in it. |
A small interesting point about this topic, from an unrelated project https://chromium-review.googlesource.com/c/chromium/src/+/927181 Chromium is disabling shadowing variables at build time. |
It's important to clarify what kinds of shadowing are disallowed. Is all shadowing disallowed? For example, since We don't want a bunch of special cases for shadowing rules. But banning all shadowing makes it that much harder to pick clear, succinct identifiers in all cases. |
I think the rule "shadowing is allowed with |
This is covered by the discussion in #377. |
This is a follow up to the original proposal: #9818
The following code will alias the
logw
variable and introduce a bug in all the code that falls in thedefault
label.logw
is declared outside the switch case (and correctly initialized to nil), but then anotherlogw
is created together with err in the default case. This will result inlogw
being always set to nil if the code goes through the default case.This is a mistake that both newbie and seasonal go developers do. In my opinion, aliasing in general should be avoided in all cases, since compatibility is relevant in this first phase, maybe the
:=
syntax could be made a bit smarter and reuse an already existing variable (at least for multiple declarations, like the one in the sample code). Alternatively, although less ideal, it would be ok if auxiliary tools likego vet
could warn the user about this kind of aliasing.The text was updated successfully, but these errors were encountered: