21. Additional Exercises

Exercise A1

Write a Go program that changes the string “text” to “Text”.

Exercise A2

Why does the program below prints 116?

1 package main
2 
3 import "fmt"
4 
5 func main() {  
6         x := "text"
7         fmt.Println(x[0]) //print 116
8 }

Exercise A3

Why does the following program not compile?

 1 package main
 2 
 3 import "fmt"
 4 
 5 func main() {  
 6     data := []int{1,2,3}
 7     i := 0
 8     ++i //error
 9     fmt.Println(data[i++]) //error
10 }

Exercise A4

Why does the following program not compile?

 1 package main
 2 
 3 import (  
 4         "fmt"
 5         "log"
 6         "net/http"
 7         "io/ioutil"
 8 )
 9 
10 func check(e error, str string) {
11 	if e != nil {
12 		log.Fatal(str, " ", e)
13 		return
14 	}
15 }
16 
17 func main() {  
18         resp, err := http.Get("https://api.ipify.org?format=json")
19         defer resp.Body.Close()
20         check(err, "http.Get:")
21 
22         body, err := ioutil.ReadAll(resp.Body)
23         check(err, "ReadAll:")
24 
25         fmt.Println(string(body))
26 }

21.1 Solutions

Exercise A1 Solution1. Another solution for A12.

Exercise A2 Reason: The index operator on a string returns a byte value, not a character (like it’s done in other languages). For more details, read the topic on conversions3.

Exercise A3 Reason: Many languages have increment and decrement operators. Unlike other languages, Go doesn’t support the prefix version of the operations. You also can’t use these two operators in expressions.

Exercise A4 Reason: When you make requests using the standard http library you get a http response variable. If you don’t read the response body you still need to close it. You must do it for empty responses too. It’s very easy to forget especially. Some new Go developers do try to close the response body, but they do it in the wrong place as was done in the given program. The most common why to close the response body is by using a defer call after the http response error check.

Most of the time when your http request fails the resp variable will be nil and the err variable will be non-nil. However, when you get a redirection failure both variables will be non-nil.

A better way is:

1         resp, err := http.Get("https://api.ipify.org?format=json")
2         defer func() {if resp != nil {resp.Body.Close()}}()
3         check(err, "http.Get:")
  1. http://play.golang.org/p/p3fyS28NKy
  2. http://play.golang.org/p/iZm6VBVa8S
  3. http://golang.org/ref/spec#Conversions