I have written some code to prints the content found at a URL following the guide of a book named The Go Programming Language. The compiler complained about the following code that no new variables on left side of :=
.
package main
import (
"fmt"
"net/http"
"os"
"io"
)
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
_, err := io.Copy(os.Stdout, resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
}
}
And I have known that this was caused by re-declaration of certain variables. While the following one passed the compilation.
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
)
func main() {
for _, url := range os.Args[1:] {
resp, err := http.Get(url)
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
os.Exit(1)
}
b, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
os.Exit(1)
}
fmt.Printf("%s", b)
}
}
Didn't it re-declare the variable err
? Then how could it pass the compilation?
If there are any new variables in the assignment (e.g. b
) then := will create it. If all variables are not new then you get the error you're getting. _
is not a new variable.
Since you have all existing variables you can just use = for your io line:
_, err = io.Copy(os.Stdout, resp.Body)
When you used b
instead of _
then := declared b
but treated err
like a standard assignment (i.e. just as if a = was used)
It did not
You can use the :=
as long as there is at least one new variable at the left side and the other variables have already been declared in the same block with the same type. Already declared variables will just have their values changed. It's basically for convenience.
It is all described here : https://golang.org/ref/spec#Short_variable_declarations
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With