The five most useful packages in Go

02 Jan 2010

When Go launched a couple months back, it came with a pretty good collection of packages . I’ve been playing with the language more or less since it launched, and in that time I’ve written code that’s covered quite a few of these packages. While there are a bunch of weird ones that I’ve never used, there are several that I seem to use repeatedly. So in no particular order, these are the five most useful go packages I’ve found.

1. bytes

bytes.Buffer is probably the most useful type for working with data. It’s a dynamic-size byte buffer that lets you read and write strings or bytes. At any time you can get the underlying data in either string or byte array format. It also implements several recurring Go interfaces (io.Reader, io.Writer) which makes it usable as buffers in many other packages. I’ve found it particularly useful in the following situations:

Example:

    var buf bytes.Buffer
    buf.WriteString("This is some json: ")
    json.Marshal ( &buf, map[string]int {"a":1, "b":2})
    println ( buf.String() ) 
    //prints: This is some json: {"a":1,"b":2}

2. reflect

Reflect is a powerful package that lets you do runtime type inspection. Although Go is a statically typed language, many functions can work with generic data through the use of the generic type : interface{}. This is especially useful in packages that do serialization or data storage.

For instance, we can write a simple method that prints some details about the argument:

func printMyType(val interface{}) {
		fmt.Printf("Val is: \n")
		switch v := reflect.NewValue(val).(type) {
		case *reflect.StringValue:
				fmt.Printf("string %q", v.Get())
		case *reflect.IntValue:
				fmt.Printf("int %d", v.Get())
		case *reflect.MapValue:
				fmt.Printf("map with %d keys:\n", v.Len())
				for _, k := range (v.Keys()) {
						fmt.Printf(" %v: %v\n", k.Interface(), v.Elem(k).Interface())
				}
		}
		... more type reflection
}

3. os

If you need to make a system call, you’re going to need to import this package. Anything that involves calling the underlying system – like like forking processes, executing commands, reading/writing files, opening directories, or grabbing environment variables – go through the os package.

4. ioutil

This is a small package with just four useful methods:

  1. ReadAll - reads a data source (io.Reader) until it hits EOF
  2. ReadDir - reads the directory named by dirname and returns a list of sorted directory entries.
  3. ReadFile - reads the file named by filename and returns the contents.
  4. WriteFile - writes contents to a file by filename

5. vector

This is more or less the equivalent of python lists. It lets you implement stacks, queues, heaps, or whatever other structure you’d like on top of a list.

    var a vector.Vector
    a.Push(12)
    a.Push("hello")
    fmt.Printf("a len %d\n", len(a))
    fmt.Printf("%v\n", a[1])

So, that’s the end of this list. If anyone has packages they’ve found useful, feel free to post them here. Next time I plan to write about packages that Go desperately needs.