Erik
-------------------- Source Code Snippet -----------------------------
package main
import "fmt"
// nonWorkingLoopScan loops forever without reading any input but the first two
func nonWorkingLoopScan() {
var p, q int
for n, err := fmt.Scanf("%d %d", &p, &q); n == 2 && err == nil; /* nothing more */ {
fmt.Println(p, q)
}
}
// workingLoopScan acquires every input and eventually terminates (newline, malformed line, EOF, ...)
func workingLoopScan() {
for {
var p, q int
if n, err := fmt.Scanf("%d %d", p, q); n != 2 || err != nil {
break
}
fmt.Println(p, q)
}
}
func main() {
workingLoopScan()
nonWorkingLoopScan()
}
-------------------- End of Source Code Snippet -----------------------------
I think the second semi-colon here is what's getting you. this loop is
equivalent to
n, err = scanf
while n == 2 && err == nil:
print...
You only ever call scanf once.
personally, i think it would be nice if that fragment worked as you
expected, but i think you
actually want something like this:
for {
n, err := fmt.Scanf("%d %d", &p, &q)
if n != 2 || err != nil {
break
}
fmt.Println(p, q)
}
Yes, this is completely expected.
http://golang.org/doc/go_spec.html#For_statements
Go's for loops work exactly the same as C,C++,Java, etc.
> // nonWorkingLoopScan loops forever without reading any input but the first two
> func nonWorkingLoopScan() {
> var p, q int
>
> for n, err := fmt.Scanf("%d %d", &p, &q); n == 2 && err == nil; /* nothing more */ {
> fmt.Println(p, q)
> }
> }
You're missing the 'PostStmt'
ie. You probably want something like:
for n, err := fmt.Scanf("%d %d", &p, &q); n == 2 && err == nil; n, err
= fmt.Scanf("%d %d", &p, &q) {
fmt.Println(p, q)
}
- jessta
--
=====================
http://jessta.id.au
// workingLoopScan acquires every input and eventually terminates (newline, malformed line, EOF, ...)
func workingLoopScan() {
for {
var p, q int
if n, err := fmt.Scanf("%d %d", &p, &q); n != 2 || err != nil {
break
}
fmt.Println(p, q)
}
}
But I still do not get why the following is incorrect:
// nonWorkingLoopScan loops forever without reading any input but the first two
func nonWorkingLoopScan() {
var p, q int
for n, err := fmt.Scanf("%d %d", &p, &q); n == 2 && err == nil; /* nothing more */ {
fmt.Println(p, q)
}
}
I have checked the code using production rules (language specs) and it seems perfectly legal to have an EmptyStmt (which is a SimpleStmt) as PostStmt in a ForClause (ie. the second ";" should not get in the way as suggested by Corey). Moreover, i expect the compiler to produce (almost) the same binary code for the workingLoopScan() and nonWorkingLoopScan() functions and this is obviously not the case in the current release.
By the way, I have also noticed that omitting "&" in fmt.Scanf as in "fmt.Scanf("%d %d", p, q)" doesn't produce any error during compilation nor runtime.
e.
You are right!
In the process of rewriting "while" using "for" I was confused. It is indeed totally expected in a for loop to have an initStmt which runs once (init after all) and a postStmt to run every time!
Sorry for the last message ;)
e.