The following tiny program does not work correctly:
////////////////////////////////////////////////////////////
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
var input *os.File
if len(os.Args) == 1 {
input = os.Stdin
} else {
input, err := os.Open(os.Args[1], os.O_RDONLY, 0)
if err != nil {
panic(err)
}
defer input.Close()
}
reader := bufio.NewReader(input)
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
fmt.Print(line)
}
}
////////////////////////////////////////////////////////////
If built as "test" then:
$ ./test
blah
blah
works fine, but
$ ./test datafile
outputs nothing.
If I change the program to:
////////////////////////////////////////////////////////////
package main
// as before
func main() {
var input *os.File
var err os.Error // NEW
if len(os.Args) == 1 {
input = os.Stdin
} else {
input, err = os.Open(os.Args[1], os.O_RDONLY, 0) // CHANGED
// as before
////////////////////////////////////////////////////////////
it works fine in both cases.
In the Specification it says:
"Unlike regular variable declarations, a short variable declaration
may redeclare variables provided they were originally declared in
the same block ... and at least one of the non-blank variables is
new. ... Redeclaration does not introduce a new variable; it just
assigns a new value to the original."
In the first version err is a new variable so I'm expecting input to get
assigned the *os.File returned by os.Open.
So is this a bug, or have I misunderstood?
Thanks!
PS
$ hg identify
a7800e20064a+ release/release.2010-11-10
--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy
"Programming in Python 3" - ISBN 0321680561
http://www.qtrac.eu/py3book.html
Eoghan
So it was my misunderstanding.
Thanks!
--
Mark Summerfield, Qtrac Ltd, www.qtrac.eu
C++, Python, Qt, PyQt - training and consultancy
"Advanced Qt Programming" - ISBN 0321635906
http://www.qtrac.eu/aqpbook.html
I wasn't aware of the variable redeclaration clause before this
thread. It seems to only be of use when you have a sequence of
declarations which rely on an accumulated value. So instead of
var field1, field2 Field
var offset int
field1, offset = nextField(str, 0)
field2, offset = nextField(str, offset)
you can write
field1, offset := nextField(str, 0)
field2, offset := nextField(str, offset)
I would use the second form sparingly, if at all, since it breaks
how := is read.
Eoghan
The semantics of x:=y and x=y are different. Reading them both as
"x is y" seems like a bad idea. Of course, "x is defined
to be a variable initialized to y" is purposefully verbose. It's
internalized to a more efficient form.
Eoghan