Alan A. A. Donovan and Brian W. Kernighan, The Go Programming Language. Addison-Wesley, 2016, Chapter 1, Tutorial

See also Go: getting oriented

Exercise 1.1

Modify the echo program to also print os.Args[0], the name of the command that invoked it.

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
    "fmt"
    "os"
    "strings"
)

func main() {
    fmt.Print(os.Args[0] + " ")
    fmt.Println(strings.Join(os.Args[1:], " "))
}

Exercise 1.2

Modify the echo program to print the index and value of each of its arguments, one per line.

1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
    "fmt"
    "os"
)

func main() {
    for idx, elt := range os.Args {
        fmt.Println(idx, elt)
    }
}

Exercise 1.3

Experiment to measure the difference in running time between our potentially inefficient versions and the one that uses strings.Join. (Section 1.6 illustrates part of the time package, and Section 11.4 shows how to write benchmark tests for systematic performance evaluation.)

Solution 1

Using time:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package main

import (
    "fmt"
    "os"
    "strings"
    "time"
)


func args1() {
    var s, sep string
    for i := 1; i < len(os.Args); i++ {
        s += sep + os.Args[i]
        sep = " "
    }
    fmt.Println(s)
}


func args2() {
    fmt.Println(strings.Join(os.Args, " "))
}


func main() {
    start := time.Now()
    args1()
    fmt.Printf("%0.2f s elapsed\n", time.Since(start).Seconds())

    start = time.Now()
    args2()
    fmt.Printf("%0.2f s elapsed\n", time.Since(start).Seconds())
}

Solution 2

Using benchmark functions included in a test file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main

import "testing"


func BenchmarkArgs1(b *testing.B) {
    for i := 0; i < b.N; i++ {
        args1()
    }
}


func BenchmarkArgs2(b *testing.B) {
    for i := 0; i < b.N; i++ {
        args2()
    }
}