Getting Started with Go

Tweet

Unless you’ve been living under a rock these last few years, you’ll have heard of Go (sometimes referred to as Golang), a language originating from Google, some years ago.

Go is slated as:

…an open source programming language that makes it easy to build simple, reliable, and efficient software.

Quoting another source, Go

is a statically-typed language with syntax loosely derived from that of C, adding automatic memory management, type safety, some dynamic-typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library.

Available for most modern operating systems, including Mac OS X, Linux, BSD and Microsoft Windows, it was conceived and initially created at Google, back in 2007, by Robert Griesemer, Rob Pike, and Ken Thompson. Each of these three developers have quite impressive pedigrees.

Robert Griesemer was involved in Google’s V8 JavaScript engine and the Java HotSpot virtual machine; Rob Pike and Ken Thompson both worked at Bell Labs implementing the original UNIX operating system.

Most programming languages, especially one with such a strong C heritage, can be difficult to get started with. Go on the other hand, is quite the opposite. And in today’s tutorial, I’m going to show you how to get started developing with Google Go, right from installation to a running application.

Go Installation

Whether you’re on Mac OS X, Linux and FreeBSD, or Windows, Go is easy to install and configure. I’m assuming in this tutorial that you have a UNIX/Linux operating system. When I first installed Go, being on a Mac, I used the latest package file.

But you can just as easily install, from source, using the following commands:

tar -C /usr/local -xzf go1.2.1.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

If you’re not familiar, these will extract a copy of the go files, from go1.2.1.linux-amd64.tar.gz, to /usr/local/go in your filesystem, and add the bin directory within it to your profile path.

Alternatively, if you’re on Windows, download and run the MSI Installer.

When the installer’s complete, you’ll find the installed files under c:\Go; and the installer should have added c:\Go\bin to your PATH environment variable. You may want to check, just to be sure though.

Configuring Your Environment

With that done, we have the binaries required to begin. But we need to ensure that our environment’s also ready, which requires one more step and a bit of background.

Go development uses the concept of a workspace, which contains the source files (src), compiled binary files (bin) and packages (pkg).

The source file directory structure, generally, models open source code repositories, such as Github. So a typical source directory could look as follows:

    src
        github.com
        settermjd   
        sitepoint
                hello-world.go

You can see that under src, I’ve linked to my Github repository, called sitepoint, and in it is one file, hello-world.go.

I could have multiple repositories, and link to multiple hosts, including Bitbucket and Codebase. By taking this approach, I believe that Go inherently keeps code very well structured and organized.

Because of that structure, the Go compiler requires a system variable, GOPATH, to be set, pointing to the root of this directory. So, let’s get our GOPATH directory created and the environment variable set.

In today’s tutorial, I’ll be creating it in my home directory. But depending on where you usually keep your code files, feel free use that instead.

Running the following command will create the required directory structure, via the -p switch, in one step and set the GOPATH environment variable.

mkdir -p /Users/settermjd/go/src/github.com/settermjd/sitepoint
export GOPATH=/Users/settermjd/go

If you’re using Windows, don’t forget to add a GOPATH environment variable. With that done, we’re ready to create our first Go application.

A Simple Application

To keep things simple, I’ve only covered a small set of the language features. But in future posts, we’ll build on what we’ve covered here.

Instead of looking at a set of language features, we’ll be working through an annotated application which shows how to print out a simple statement, based on reading the contents of a JSON string, along with some conditional logic.

An unannotated version of the code below is available on Github. Feel free to clone it and work through it as you step through the tutorial. But otherwise, lets work through the annotated version below.

package main

Every Go application is made up of packages and, using a Java reference, programs use the main package as the default.

import ( 
    "encoding/json"
    "fmt"
    "strings"
)

As I mentioned at the start of the tutorial, Go has a rather large standard library. To access that functionality, you need to import the specific packages you need.

Here, I’ve imported three: encoding/json, fmt, and strings. If it seems foreign, it really shouldn’t. In PHP and C you’d use includes (or requires), in Python you’d use imports and in Ruby you’d use require.

The available package list is quite extensive. So if you’re curious about the rest, or want more specific information on the above three, grab yourself a coffee and checkout the documentation. Full coverage is well outside of the limits of this tutorial.

type User struct {
    FirstName string `json:"first_name"`
    LastName string `json:"last_name"`
    Age int
    Languages []string `json:"languages"`
}

Go doesn’t implement classes, but Structs go a long way to providing that functionality, which we’ll see in later tutorials. For now, structs are a handy way of storing collections of named information.

In the above example, I’ve declared a struct, called User. It has four fields: FirstName, LastName, Age and Languages. Here we can see usage of some of the core Go Data Types. FirstName and LastName are strings, Age is an int and Languages is an array of strings.

At the end of each of these, you’ll see json:"first_name". What this does, potentially a bit beyond the scope of an intro example, is help map the struct field to a field in a JSON string we’ll see shortly.

func printUserData(jsonData string, age int) string {

Here we’ve defined a function called printUserData, which takes two parameters, a string called jsonData and an int called age, and will return a string.

var output string

Here I’ve declared a variable called output, which has the type string.

res := &User{}

Here I’ve both declared a variable, res which will be the of the custom User struct we defined earlier. Here’s an example of both defining a variable to a set type and initializing it in one go.

json.Unmarshal([]byte(jsonData), &res)

Here we’ve called the Unmarshal function in the json package, passing in the first argument jsonData, and the res Struct variable.

if res.Age > age {
    output = fmt.Sprintf("User %s %s, who's %d can code in the following languages: %s\n", res.FirstName, res.LastName,  res.Age, strings.Join(res.Languages, ", "))    
} else {
    output = fmt.Sprintf("User %s %s must be over %d before we can print their details", res.FirstName, res.LastName, age)
}

This section will likely seem quite familiar, whether your background is PHP, Java, C/C++, Python, Ruby, or JavaScript; with one small change. In Go, if statements don’t require parenthesis, but do require curly braces.

Here I’m checking if the age of the person, in the converted JSON object, is greater than the age that was passed in as the second function argument.

If so, we print out their full name, age and the languages they can code in. If not, we print a different message, saying that we can’t show details about them.

Here we see examples of two further standard library packages: fmt.Sprintf and strings.Join. I chose these examples deliberately as they’re likely used in most common web scripting languages which you’re likely familiar with, especially PHP.

fmt.Sprintf will replace placeholders in the first argument string, with those supplied. As languages is an array, I’ve used the strings.Join function, analogous to PHP’s implode function, to convert the array to a string, separating the elements with “’, “.

The result is then assigned to the string variable output.

    return output
}

At the end of the function, we return output.

func main() {
    var age int = 24
    str := `{"first_name": "Matthew", "last_name": "Setter", "age": 21, "languages": ["php", "javascript", "go"]}`
    fmt.Println(printUserData(str, age))
}

A Go application is launched from the main function in the main package. So I’ve implemented main, initializing an integer variable to the value 24, then initialized a string variable, str, to a simple JSON string.

You can see that it contains four components:

  • first name
  • last name
  • age
  • languages

Finally I’ve called the fmt.Println method, passing in a call to the printUserData function, where I’ve passed in the str and age variables.

Compiling The Code

Unlike PHP, Ruby, Python etc, Go is a compiled language. So from your project directory, in my case /Users/settermjd/go/src/github.com/settermjd/sitepoint, run the following command:

go install

This will compile a go binary in the bin/ directory, naming it sitepoint, after the package name. To run it, just call it as you would any other system binary, or executable, e.g.

$GOPATH/bin/sitepoint

The result will be:

User Matthew Setter must be over 24 before we can print their details

In Conclusion

So there you go, a hands on example, showing the basics of how to develop with Go. I hope that this example’s given you both a good introduction to Go basics, as well as shown you just how easy it is to get started.

I’m relatively new to Go myself, and actively learning. But if you’re interested in exploring Go with me, then join me in the upcoming tutorials, over the coming weeks and months, and let’s learn this exciting, fun, and very interesting language together.

If you’d like more information check out the following, excellent, examples:

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Jamie Devine

    Thanks – that’s a nice intro.

    However, I have a noob question – how would you use Go in the ‘real world’? In your example you write a program to run from the command line, but how would this fit into a real web application and what would be a typical use case for something like this? Is it a substitute for PHP?

    • Taylor Ren

      Go also has a framework to do frontend: Beego. If you would like to setup your web app purely in Go, you may want to consider Beego.

      In my practice, I will still choose PHP/Symfony/Dart as frontend development scripts, some backend: RESTful API for instance, can be supported by Go, Dart (and many other options/configurations).

      For your reference.

      • Jamie Devine

        Cheers for the info, I’ll take a look at Beego.

      • http://www.matthewsetter.com/ Matthew Setter

        Hi Taylor, thanks for the link to Beego. I’m aware of both Martini and Gorilla, but have not experimented much with either as yet. Some colleagues who have more experience suggest that of the two, Gorilla is likely better to begin with. What’s your experience?

        • Taylor Ren

          Hi Matthew,

          Frankly speaking, I have not used any of them: Martini, Gorilla, or Beego as most of the time, I will use Dart and or PHP to provide backend stuffs.

          So I’m afraid I can’t contribute too much on this particular topic.

          However, on Go itself, I would recommend one small and free book written by Caleb Doxsey: An Introduction To Programming In Go. There is free download available. It is a very good entry level Go book.

          Cheers!

          • http://www.matthewsetter.com/ Matthew Setter

            Hey Taylor, that sounds like just the book I’m looking for to continue my journey in Go. I’ll be checking it out today!

        • http://ch-linghu.me ch.linghu

          Gorilla is more like a toolkit than a framework. Golang already has a build-in tiny web framework. however, you have to do many routine works if you just use the build-in. Gorilla encapsulates many common tasks so it’s convenient for the development. However, it has to work with an existing framework.

          I know little about Martini. I just feel that it’s a bit magic because of the injection mechanism. I tried to write a sample project with martini but failed to run.

          beego is more easier to understand and easy to use with the command tool named ‘bee’. I used it to write some small json APIs and they worked just well.

          • Taylor Ren

            Thanks @chlinghu:disqus

            @Matthew, ch.linghu is a friend of mine. He knows much more about Go than I do.

          • http://www.matthewsetter.com/ Matthew Setter

            hey @chlinghu:disqus, thanks for the clarification. Friends have remarked that Martini may be a bit too hard to understand for beginners, like myself, because of the “reflection magic” which is going on. Beego sounds like the one for me then.

          • Taylor Ren

            Maybe we can invite @chlinghu:disqus to write an intro for Beego. Who is the editor for this channel? Can you link him up?

          • http://www.matthewsetter.com/ Matthew Setter

            Hey Taylor, sorry for the delay in getting back to you. @LouisLazaris:disqus is the editor for the channel.

          • http://www.matthewsetter.com/ Matthew Setter

            I’ve had a look at Gorilla, Martini and Beego since I wrote this post and of all of them, to me Beego makes the most sense. From experimenting with it, Beego’s a really wicked framework for getting up and running really quickly. I’ve not gone through all of the documentation yet, but from what I have – what a breath of fresh air.

    • http://www.matthewsetter.com/ Matthew Setter

      Jamie, it definitely can be. If you’re keen to see more about PHP in comparison to Go, here’s an excellent link from David Gardner on the topic: http://www.davegardner.me.uk/blog/2013/07/16/from-php-to-go/

  • http://evanbyrne.com Evan Byrne

    Solid introduction to the language. I’m looking forward to seeing more Go posts!

    • http://www.matthewsetter.com/ Matthew Setter

      Hi Evan, I really appreciate your feedback and support. I’m keen to keep exploring, learning and writing more to share what I know with others here on Sitepoint. What are your suggestions for blogs to read and twitter accounts to follow?

  • Jamie Devine

    Thanks for sharing your source code, this is very helpful.

  • http://www.matthewsetter.com/ Matthew Setter

    Hi Evan, thanks for sharing the source of your website mate. As someone relatively new to Go, I’m really keen to learn all that I can and this, I’m sure, will be a great help.

  • Anthony

    Good stuff. I would also mention `go run hello-world.go` as a way to run the code to test prior to install. Maybe encourage testing early on as well. Great habit to get into and Go has built in testing

    • http://www.matthewsetter.com/ Matthew Setter

      Fantastic suggestion @AntneeC:disqus

  • John_Betong

    Link “The Go Blog” is incorrect. – “404: Page not found”

    http://www.sitepoint.com/getting-started-go/blog.golang.org/

    • LouisLazaris

      Thanks, fixed. :)

  • http://www.matthewsetter.com/ Matthew Setter

    @masnun:disqus thanks for the links, especially the comparison on the Square blog. It’s always good to keep getting input and different perspectives; especially on such a relatively new language as Go. It’s interesting to see that the net/http package is considered the best one to start with. That sentiment comes through a lot on the Go Slack channel.