Go

Topics related to Go:

Getting started with Go

Go is an open-source, compiled, statically typed language in the tradition of Algol and C. It boasts features such as garbage collection, limited structural typing, memory safety features, and easy-to-use CSP-style concurrent programming.

Functions

Structs

Concurrency

Goroutines in Go are similar to threads in other languages in terms of usage. Internally, Go creates a number of threads (specified by GOMAXPROCS) and then schedules the goroutines to run on the threads. Because of this design, Go's concurrency mechanisms are much more efficient than threads in terms of memory usage and initialization time.

Arrays

Packages

Variables

Maps

Go provides a built-in map type that implements a hash table. Maps are Go's built-in associative data type (also called hashes or dictionaries in other languages).

Slices

HTTP Server

http.ServeMux provides a multiplexer which calls handlers for HTTP requests.

Alternatives to the standard library multiplexer include:

Error Handling

Note how in Go you don't raise an error. Instead, you return an error in case of failure.

If a function can fail, the last returned value is generally an error type.

// This method doesn't fail
func DoSomethingSafe() {
}

// This method can fail
func DoSomething() (error) {
}

// This method can fail and, when it succeeds,
// it returns a string.
func DoAndReturnSomething() (string, error) {
}

Loops

Vendoring

Vendoring is a method of ensuring that all of your 3rd party packages that you use in your Go project are consistent for everyone who develops for your application.

When your Go package imports another package, the compiler normally checks $GOPATH/src/ for the path of the imported project. However if your package contains a folder named vendor, the compiler will check in that folder first. This means that you can import other parties packages inside your own code repository, without having to modify their code.

Vendoring is a standard feature in Go 1.6 and up. In Go 1.5, you need to set the environment variable of GO15VENDOREXPERIMENT=1 to enable vendoring.

JSON

The package "encoding/json" Package json implements encoding and decoding of JSON objects in Go.


Types in JSON along with their corresponding concrete types in Go are:

JSON TypeGo Concrete Type
booleanbool
numbersfloat64 or int
stringstring
nullnil

Cross Compilation

Supported Operating System and Architecture target combinations (source)

$GOOS$GOARCH
androidarm
darwin386
darwinamd64
darwinarm
darwinarm64
dragonflyamd64
freebsd386
freebsdamd64
freebsdarm
linux386
linuxamd64
linuxarm
linuxarm64
linuxppc64
linuxppc64le
linuxmips64
linuxmips64le
netbsd386
netbsdamd64
netbsdarm
openbsd386
openbsdamd64
openbsdarm
plan9386
plan9amd64
solarisamd64
windows386
windowsamd64

File I/O

Constants

Go supports constants of character, string, boolean, and numeric values.

Executing Commands

Interfaces

Interfaces in Go are just fixed method sets. A type implicitly implements an interface if its method set is a superset of the interface. There is no declaration of intent.

Testing

Pointers

Channels

A channel holding the empty struct make(chan struct{}) is a clear message to the user that no information is transmitted over the channel and that it's purely used for synchronization.

Regarding unbuffered channels, a channel write will block until a corresponding read occurs from another goroutine. The same is true for a channel read blocking while waiting for a writer.

SQL

For a list of SQL database drivers see the official Go wiki article SQLDrivers.

The SQL drivers are imported and prefixed by _, so that they are only available to driver.

Branching

Templates

Golang provides packages like:

  1. text/template

  2. html/template

to implement data-driven templates for generating textual and HTML outputs.

HTTP Client

It is important to defer resp.Body.Close() after every HTTP request that does not return a non-nil error, else resources will be leaked.

XML

While many uses of the encoding/xml package include marshaling and unmarshaling to a Go struct, it's worth noting that this is not a direct mapping. The package documentation states:

Mapping between XML elements and data structures is inherently flawed: an XML element is an order-dependent collection of anonymous values, while a data structure is an order-independent collection of named values.

For simple, unordered, key-value pairs, using a different encoding such as Gob's or JSON may be a better fit. For ordered data or event / callback based streams of data, XML may be the best choice.

Reflection

The reflect docs are a great reference. In general computer programming, reflection is ability of a program to examine the structure and behavior of itself at runtime.

Based on its strict static type system Go lang has some rules (laws of reflection)

YAML

Build Constraints

Build tags are used for conditionally building certain files in your code. Build tags may ignore files that you don't want build unless explicitly included, or some predefined build tags may be used to have a file only be built on a particular architecture or operating system.

Build tags may appear in any kind of source file (not just Go), but they must appear near the top of the file, preceded only by blank lines and other line comments. These rules mean that in Go files a build constraint must appear before the package clause.

A series of build tags must be followed by a blank line.

Mutex

Inline Expansion

Inline expansion is a common optimization in compiled code that prioritized performance over binary size. It lets the compiler replace a function call with the actual body of the function; effectively copy/pasting code from one place to another at compile time. Since the call site is expanded to just contain the machine instructions that the compiler generated for the function, we don't have to perform a CALL or PUSH (the x86 equivalant of a GOTO statement or a stack frame push) or their equivalant on other architectures.

The inliner makes decisions about whether or not to inline a function based on a number of heuristics, but in general Go inlines by default. Because the inliner gets rid of function calls, it effectively gets to decide where the scheduler is allowed to preempt a goroutine.

Function calls will not be inlined if any of the following are true (there are many other reasons too, this list is incomplete):

  • Functions are variadic (eg. they have ... args)
  • Functions have a "max hairyness" greater than the budget (they recurse too much or can't be analyzed for some other reason)
  • They contain panic, recover, or defer

Closures

Context

The context package (in Go 1.7) or the golang.org/x/net/context package (Pre 1.7) is an interface for creating contexts that can be used to carry request scoped values and deadlines across API boundaries and between services, as well as a simple implementation of said interface.

aside: the word "context" is loosely used to refer to the entire tree, or to individual leaves in the tree, eg. the actual context.Context values.

At a high level, a context is a tree. New leaves are added to the tree when they are constructed (a context.Context with a parent value), and leaves are never removed from the tree. Any context has access to all of the values above it (data access only flows upwards), and if any context is canceled its children are also canceled (cancelation signals propogate downwards). The cancel signal is implemented by means of a function that returns a channel which will be closed (readable) when the context is canceled; this makes contexts a very efficient way to implement the pipeline and cancellation concurrency pattern, or timeouts.

By convention, functions that take a context have the first argument ctx context.Context. While this is just a convention, it's one that should be followed since many static analysis tools specifically look for this argument. Since Context is an interface, it's also possible to turn existing context-like data (values that are passed around throughout a request call chain) into a normal Go context and use them in a backwards compatible way just by implementing a few methods. Furthermore, contexts are safe for concurrent access so you can use them from many goroutines (whether they're running on parallel threads or as concurrent coroutines) without fear.

Further Reading

Defer

Defer works by injecting a new stack frame (the called function after the defer keyword) into the call stack below the currently executing function. This means that defer is guaranteed to run as long as the stack will be unwound (if your program crashes or gets a SIGKILL, defer will not execute).

Type conversions

Iota

The iota identifier is used to assign values to lists of constants. When iota is used in a list it starts with a value of zero, and increments by one for each value in the list of constants and is reset on each const keyword. Unlike the enumerations of other languages, iota can be used in expressions (eg. iota + 1) which allows for greater flexibility.

Fmt

Select and Channels

Logging

Text + HTML Templating

Methods

Parsing Command Line Arguments And Flags

Worker Pools

Panic and Recover

Base64 Encoding

The encoding/base64 package contains several built in encoders. Most of the examples in this document will use base64.StdEncoding, but any encoder (URLEncoding, RawStdEncodign, your own custom encoder, etc.) may be substituted.

OS Signals

Memory pooling

The Go Command

Installation

Parsing CSV files

Send/receive emails

Zero values

One thing to note - types that have a non-nil zero value like strings, ints, floats, bools and structs can't be set to nil.

cgo

Installation

Downloading Go

Visit the Downloads List and find the right archive for your operating system. The names of these downloads can be a bit cryptic to new users.

The names are in the format go[version].[operating system]-[architecture].[archive]

For the version, you want to choose the newest available. These should be the first options you see.

For the operating system, this is fairly self-explanatory except for Mac users, where the operating system is named "darwin". This is named after the open-source part of the operating system used by Mac computers.

If you are running a 64-bit machine (which is the most common in modern computers), the "architecture" part of the file name should be "amd64". For 32-bit machines, it will be "386". If you're on an ARM device like a Raspberry Pi, you'll want "armv6l".

For the "archive" part, Mac and Windows users have two options because Go provides installers for those platforms. For Mac, you probably want "pkg". For Windows, you probably want "msi".

So, for instance, if I'm on a 64-bit Windows machine and I want to download Go 1.6.3, the download I want will be named:

go1.6.3.windows-amd64.msi

Extracting the download files

Now that we have a Go archive downloaded, we need to extract it somewhere.

Mac and Windows

Since installers are provided for these platforms, installation is easy. Just run the installer and accept the defaults.

Linux

There is no installer for Linux, so some more work is required. You should have downloaded a file with the suffix ".tar.gz". This is an archive file, similar to a ".zip" file. We need to extract it. We will be extracting the Go files to /usr/local because it is the recommended location.

Open up a terminal and change directories to the place where you downloaded the archive. This is probably in Downloads. If not, replace the directory in the following command appropriately.

cd Downloads

Now, run the following to extract the archive into /usr/local, replacing [filename] with the name of the file you downloaded.

tar -C /usr/local -xzf [filename].tar.gz

Setting Environment Variables

There's one more step to go before you're ready to start developing. We need to set environment variables, which is information that users can change to give programs a better idea of the user's setup.

Windows

You need to set the GOPATH, which is the folder that you will be doing Go work in.

You can set environment variables through the "Environment Variables" button on the "Advanced" tab of the "System" control panel. Some versions of Windows provide this control panel through the "Advanced System Settings" option inside the "System" control panel.

The name of your new environment variable should be "GOPATH". The value should be the full path to a directory you'll be developing Go code in. A folder called "go" in your user directory is a good choice.

Mac

You need to set the GOPATH, which is the folder that you will be doing Go work in.

Edit a text file named ".bash_profile", which should be in your user directory, and add the following new line to the end, replacing [work area] with a full path to a directory you would like to do Go work in. If ".bash_profile" does not exist, create it. A folder called "go" in your user directory is a good choice.

export GOPATH=[work area]

Linux

Because Linux doesn't have an installer, it requires a bit more work. We need to show the terminal where the Go compiler and other tools are, and we need to set the GOPATH, which is a folder that you will be doing Go work in.

Edit a text file named ".profile", which should be in your user directory, and add the following line to the end, replacing [work area] with a full path tto a directory you would like to do Go work in. If ".profile" does not exist, create it. A folder called "go" in your user directory is a good choice.

Then, on another new line, add the following to your ".profile" file.

export PATH=$PATH:/usr/local/go/bin

Finished!

If the Go tools are still not available to you in the terminal, try closing that window and opening a fresh terminal window.

Zero values

cgo

Readers

Profiling using go tool pprof

Getting Started With Go Using Atom

Developing for Multiple Platforms with Conditional Compiling

Object Oriented Programming

Interface can't be implemented with pointer receivers because *User is not User

gob

Time

mgo

Plugin

Middleware

The Signature of middleware should be (http.ResponseWriter, *http.Request) i.e. of http.handlerFunc type.

Best practices on project structure

String

Protobuf in Go

Console I/O

Goroutines

Cryptography

JWT Authorization in Go

Images