FAQ

On 02/19/2013 10:49 PM, Rui Maciel wrote:
On 02/19/2013 07:20 AM, Johann Höchtl wrote:
quick assignemnts, := , are meant to help the programmer and give the
language the feeling being a duck-typed, dynamic language yet with the
powers of static type checking. Unfortunately this feature comes at the
price of introducing nasty, hard to spot shadowing bugs.
Go's short variable declaration doesn't introduce bugs. What tends to
introduce bugs is people using short variable declarations expecting it
to do an assignment instead of actually declaring a variable. The
example you've presented below is one of those cases.
This is not what I am talking about. Please see my comments below yours.
Consider this program:

http://play.golang.org/p/nroI2nSKyG

package main

import "fmt"

func answertoeverything(idx int) bool {
return true
}

func main() {

var answer string
var found bool
for idx := range []int{1, 3, 5} {
if found := answertoeverything(idx); found == true {
You've explicitly told the compiler to declare a new variable accessible
through the identifier "found", whose scope is limited to the block
where it was declared and which hides a previously declared variable
which shares the same identifier. What did you expected from a variable
declaration?
The inner declaration of found is perfectly fine. It's an outer found
which gets declared and read, but never assigned to.
answer = "We got an answer"
break
}
From here on, the first "found" ceased to be shadowed. No surprises here.

}

if found {
fmt.Println("The answer is", answer)
} else {
fmt.Println("No answer was found")
}
}

The variable "found" is hidden. This is clearly a mistake yet get's
unspotted by the current compiler.
It's a mistake on the behalf of the programmer, because it's perfectly
valid code and it does exactly what you told it to do: declare a new
variable, and in the process shadow any variable which is accessed
through the same identifier.
See it this way. I can carry a gun in my hand aiming towards a target. I
pull the trigger and hit the target. Everything happens exactly the whay
it is expected to happen.

Suddenly an inner block jumps in ... the instructor. Me, a gun in my
hand, the instructor in between and on the other side the target. I pull
the trigger.

Still ... everything happens exactly the way it is told to behave. Which
still makes the end results not a desirable result. Adding an "inner
block", which by itself is behaving in a fully specified way,
influences the whole.

Somewhat odd I admit, but you may get what I mean?
This is either a plain bug, or, if not,
I suppose to change the behaviour in that simply accessing a variable is
not enough to silence the compiler, but either assigning to it or taking
it'd address.

_ := silence

is seen very often and suffices to calm the compiler. I would suggest,
that
only a proper assignment can silence the "introduced but not used" error,
or taking the address of such a variable as eg. in

callfunc(&notused)

Thus

_ := silence
would become
_ := &silence

If this variable get's actually used at a a later point, it is most
likely
that it will not be used in a pointer context, in such as the programmer
can still benefit from the compilers analysis.
There is a simpler and better solution: use a short variable declaration
when you actually want to declare a variable, and use an assignment
operator when all you want to do is assign a value to a variable which
you've previously declared. This doesn't require any change to either
the language or the compiler, particularly one which is that cryptic.


Rui Maciel

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

Discussion Posts

Previous

Follow ups

Related Discussions

People

Translate

site design / logo © 2021 Grokbase