code review for count then sort problems (go lang) the question is simple, for a input [apple, banana, orange, apple, banana, apple], the program will count it as a map: {apple : 3, orange: 1, banana: 2}, then sort this map by it's values, get [(apple, 3), (banana, 2), (orange, 1)]
below is my go version, I'm a go newbie, could you please review it and lecture me how to polish the code? I add a python version for reference

package main

//input, a url.log file, like "apple\nbanana\norange\napple\nbanana\napple\n"
//output, a output.txt file, should be "apple: 3\nbanana: 2\norange: 1\n"
import (
    "fmt"
    "bufio"
    "os"
    "sort"
    "strings"
    "io"
)

func main() {
    m := make(map[string]int)

    // read file line by line
    filename := "url.log"
    f, err := os.Open(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    defer f.Close()
    r := bufio.NewReader(f)
    for line, err := r.ReadString('\n'); err == nil; {
        url := strings.TrimRight(line, "\n")
        m[url] += 1  // build the map
        line, err = r.ReadString('\n')
    }

    if err != nil {
        fmt.Println(err)
        return
    }

    //sort the map by it's value
    vs := NewValSorter(m)
    vs.Sort()

    // output
    f_out, _ := os.Create("output.go.txt") 
    defer f_out.Close()
    var line string
    for i, k := range vs.Keys {
        line = fmt.Sprintf("%s: %d\n", k, vs.Vals[i])
        io.WriteString(f_out, line)
    }

}

type ValSorter struct {
    Keys []string
    Vals []int
}

func NewValSorter(m map[string]int) *ValSorter {
    vs := &amp;ValSorter {
        Keys: make([]string, 0, len(m)),
        Vals: make([]int, 0, len(m)),
    }
    for k, v := range m {
        vs.Keys = append(vs.Keys, k)
        vs.Vals = append(vs.Vals, v)
    }
    return vs
}

func (vs *ValSorter) Sort() {
    sort.Sort(vs)
}

func (vs *ValSorter) Len() int {
    return len(vs.Vals)
}

func (vs *ValSorter) Less(i, j int) bool {
    return vs.Vals[i] &gt; vs.Vals[j]
}

func (vs *ValSorter) Swap(i, j int) {
    vs.Vals[i], vs.Vals[j] = vs.Vals[j], vs.Vals[i]
    vs.Keys[i], vs.Keys[j] = vs.Keys[j], vs.Keys[i]
}


python version:

from collections import Counter

def main():
    count = Counter()
    with open("url.log", "rb") as f:
        for line in f:
            url = line.rstrip()
            count[url] += 1
    with open("output.py.txt", "wb") as f:
        for key, value in count.most_common():
            f.write("%s: %d\n" %(key, value))


if __name__ == "__main__":
    main()
In Go, I would write:

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
    "sort"
)

type Key string
type Count int

type Elem struct {
    Key
    Count
}

type Elems []*Elem

func (s Elems) Len() int {
    return len(s)
}

func (s Elems) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

type ByReverseCount struct{ Elems }

func (s ByReverseCount) Less(i, j int) bool {
    return s.Elems[j].Count &lt; s.Elems[i].Count
}

func main() {
    m := make(map[Key]Count)
    fi, err := os.Open("keys.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer fi.Close()
    r := bufio.NewReader(fi)
    for {
        line, err := r.ReadString('\n')
        if err != nil {
            if err == io.EOF &amp;&amp; len(line) == 0 {
                break
            }
            fmt.Println(err)
            return
        }
        key := line[:len(line)-1]
        m[Key(key)] += 1
    }
    fi.Close()

    e := make(Elems, 0, len(m))
    for k, c := range m {
        e = append(e, &amp;Elem{k, c})
    }
    sort.Sort(ByReverseCount{e})

    fo, err := os.Create("counts.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer fo.Close()
    for _, e := range e {
        line := fmt.Sprintf("%s: %d\n", e.Key, e.Count)
        fo.WriteString(line)
    }
}


Input (keys.txt):

apple
banana
orange
apple
banana
apple


Output (counts.txt):

apple: 3
banana: 2
orange: 1