Wilson Mar bio photo

Wilson Mar


Email me Calendar Skype call

LinkedIn Twitter Gitter Instagram Youtube

Github Stackoverflow Pinterest

This is what the cool kids are using to create fast and portable apps

US (English)   Español (Spanish)   Français (French)   Deutsch (German)   Italiano   Português   Cyrillic Russian   中文 (简体) Chinese (Simplified)   日本語 Japanese   한국어 Korean


This is a quick step-by-step introduction to the Go programming language (GoLang).

TL;DR; Summary

Go is an opinionated language:

  • Compiler doesn’t issue warnings, just errors
  • Unused local variables are an error
  • fmt, a contraction of “format” (pronounced “frumpt”) is Go’s single way to format output

Like C:

  • Uses its own compiler to create itself. The Go compiler is programmed in Go itself rather than C. * This means Go installers don’t have dependencies like Java and Python programs.

  • Go is strongly typed (must specify data type in commands)
  • VIDEO: Used by developers of C and Unix (including Brian Kernigan, the K in awk, who literally wrote the book on C, and co-creator of Go with Alan Donovan)

Unlike C:

Unlike Python:

Like both Java and C:

  • Needs to be built by a compiler (not interpreted like Python)
  • Double slashes for comments
  • No parentheses surround the three components of the for statement

Like Java:

  • Is memory safe by default
  • Networking is baked into its standard library and runtime
  • Collects garbage automatically
  • Can be coded to be cross-platform

Unlike Java:

  • Variables are declared with external scope by being named starting with a capital letter
  • Golang does not have a “where” clause, just if.

Unlike JavaScript:

  • Go’s built-in concurrency goroutines for threads communicating through channels were not patched in over time. So Go avoids the “callback hell” associated with JavaScript’s single-thread operation. Golang can be transpiled (like BabelJs) using GopherJs into JavaScript for isomorphic web applications, where business logic, templates, template functions, and validation logic, can be shared across client and server environments, for code re-use. VIDEO: For example, http://igweb.kamesh.com built from code following the 2018 Isomorphic Go Book by Kamesh Balasubramanian.

Unlike all:

  • Go compiles fast to native code
  • Due to its small size, Go can be a good fit for use on a Raspberry Pi small computer to receive and provide small amounts of data occassionally.
  • Low GC (Garbage Collection) pause (100 microseconds)
  • Memory used is zeroed if not explicitly initialized (for security)

  • No semicolons at the end of each line
  • Coding to Go’s robust standard library (stdlib) avoids risks from including third-party JavaScript template libraries.


  • Go is generally seen as not an appropriate fit for mobile development (on iOS, Android).
  • As a relatively new language, there are not as many (as Java) who have mastered the language.

Official Go Versions (Release History)

  1. See the home page for the language:


    NOTE: “org” in the domain name indicates that it’s a not-for-profit entity.

    What is the latest versions of Go? Look at where it’s open-sourced:

  2. Click top menu “Documents”, scroll down to “Releases”, click “Release History”:


  3. Click “Minor revisions” (aka “PATCH” in Semantic Versioning parlance).

    Pre-requisite utilities

  4. Follow my tutorial to install XCode: https://wilsonmar.github.io/xcode

  5. Switch to a Terminal shell window. Press command+spacebar and type enough of “Terminal.app” for a selection to appear, then press Enter to open it.

    Install Compiler on your laptop

    The options for installing Go:

### Pay for a free language?

I haven’t had anyone recommend this to me.

Alternately, “beta” as of April, 2017 is a paid, commercially supported, quality-assured Go distribution for big data, database connectivity, code quality, microservices/cloud development, and their (XPCOM-based) multi-platform Komodo IDE:


### Multiple versions from golang.org

PROTIP: Instead of downloading installer from website from https://golang.org/dl such as download URL:

  1. To have multiple Go versions installed on the same machine, for testing install specific versions of Go, such as:

    go get golang.org/dl/go1.10.7
    go1.10.7 download
  2. To run a specific version of Go installed above:

    go1.10.7 version
  3. To uninstall a downloaded version, remove its GOROOT directory and the goX.Y.Z binary.

    Install on macOS using Homebrew

  4. In Terminal, install Homebrew by triple-clicking this command for copy to Clipboard (using command+C):

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
  5. Get Homebrew’s information about the go installer:

    brew info go

    go: stable 1.17.1 (bottled), HEAD
    Open source programming language to build simple/reliable/efficient software
    /usr/local/Cellar/go/1.17.1 (10,814 files, 565.7MB) *
      Poured from bottle on 2021-09-29 at 16:14:38
    From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/go.rb
    License: BSD-3-Clause
    ==> Options
     Install HEAD version
    ==> Analytics
    install: 112,711 (30 days), 316,523 (90 days), 1,303,820 (365 days)
    install-on-request: 91,253 (30 days), 254,580 (90 days), 1,061,594 (365 days)
    build-error: 0 (30 days)

    Note the history of growth in files and size over time:

    /usr/local/Cellar/go/1.17.1 (10,814 files, 565.7MB) *
    /usr/local/Cellar/go/1.14.4: 9,443 files, 424.7MB
    /usr/local/Cellar/go/1.13.4: 9,271 files, 414MB

    Notice there has been 1,303,820 downloads using Brew in the previous 365 days.

  6. If you use Homebrew on your Mac, install on any folder using:

    brew install go

    PROTIP: Either go or golang can be specified in the brew install command!

    Note in the example response that the installer is for a specific version of macOS (Catalina):

    ==> Downloading https://homebrew.bintray.com/bottles/go-1.13.4.mojave.bottle.tar
    ==> Downloading from https://akamai.bintray.com/2f/2fc74073a90a7073dab940868ac23
    ==> Pouring go-1.14.4.catalina.bottle.tar.gz

    PROTIP: The sample above contains “catalina”, the name of a verson of MacOS. So remember to upgrade after every macOS version upgrade (to Big Sur, etc.).

    Alternately, MacPorts:

    sudo port install go

    go version

  7. Confirm the go executable works:

    go version

    shows (at time of writing) on macOS:

    go version go1.17.1 darwin/amd64

    “darwin/amd64” is the internal name for MacOS running on a 64-bit motherboard computer.

    GOPATH (Workspace) error?

    If you get this error, read about GOPATH below:

    go: GOPATH entry is relative; must be absolute path: "$HOME/gopkgs".
    For more details see: 'go help gopath'
  8. PROTIP: Pipe to more to page break so you don’t have to scroll back up to the beginning of the file:

    go help gopath | more

    Press Enter/Return/down arrow for another line, page down or q to quit.

    It says the default folder for GOPATH is ~/go. So…

  9. Create folder ~/go (not a hidden folder):

    mkdir ~/go
  10. In ~/.bash_profile or ~/.bashrc:

    export GOPATH="$HOME/go"

    VIDEO, DOCS says: GOPATH points to the container folder where:

    • “src/github.com/wilsonmar” holds go cloned repos from a particular user/org account
    • “src/golang.org/x/website/go.mod”
    • “src/import/path”
    • “pkg” folder where compiled package files are stored based on import statements
    • “pkg/mod” folder where Go downloads modules, the default path $GOMODCACHE
    • “pkg/sumdb” folder where Go caches downloaded checksum database state

    brew Upgrade & Uninstall

  11. PROTIP: Unlike other brew modules, instead of upgrading to the latest on macOS using Homebrew:

    brew upgrade go

    If there was a previous version installed:

    On a Mac, you need to uninstall instead of upgrading:

    brew uninstall –ignore-dependencies go

    Without –ignore-dependencies you might get:

    Error: Refusing to uninstall /usr/local/Cellar/go/1.14
    because it is required by gox, which is currently installed.

    The expected response, for example:

    Uninstalling /usr/local/Cellar/go/1.14.3... (9,441 files, 424.6MB)
    Warning: The following may be go configuration files and have not been removed!
    If desired, remove them manually with `rm -rf`:

    NOTE: The above can be ignored.

    Help docs

    Go is installed with help documentation in text file:

  12. Get detailed advice about writing Go while verifying whether you can do Go commands:

    go help | more

    PROTIP: If you don’t pipe to more, you’ll see the bottom of the document and have to page back up.

    Go displays help as a page in your default text editor.

  13. If you see a colon at the lower-left corner:

    • press spacebar to page down
    • press q to quit.

    Go bug on GitHub - File an Issue

    Let’s see where the Go language is open-sourced:

  14. To create a new bug (issue) in the language, use a built-in go command to open the repository holding source code behind the Go language, in a your default browser application:

    go bug

    The associated GitHub repo is:


    Notice results from go version and go env (see below) are automatically pasted there.

    (Go’s repo was previously in Mercurial.)

    From here you can view the source code behind the Go language.

  15. Click “Insights” to see the number of authors (40 at last count) who made a commit the last week.

  16. Switch back to the Terminal (press command+tab).

Environment Variables for Go

Before downloading, consider the environment variables which define where and how files get downloaded onto your machine.

When Go is installed, several environment variables are defined.

  1. List Go’s environment settings:

    go env

    shows (at time of writing), on a Mac:

    GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j_/gh27gpxj1t58hyryfg9drvdc0000gn/T/go-build434742939=/tmp/go-build -gno-record-gcc-switches -fno-common"
    CGO_CFLAGS="-g -O2"
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"

    QUESTION: CXX=”clang++” vs CXX=”g++”

    GOROOT is in folder “usr/local/Cellar” because it was installed by Homebrew. Notice it’s for a specific version of Go. So alternately: /usr/local/opt/go/libexec/bin

    No need to define $GOROOT in ~/.bash_profile unless Go was downloaded to a custom location.


    Typically, the $GOPATH environment variable is temporarily set to quickly change to the current project workspace. GOPATH is where go get commands download stuff.


    GOROOT=”/usr/local/go” is where downloaded packages install Go (rather than Homebrew).

    See https://golang.org/ref/spec#Packages

Obtain golang-samples repository

  1. Create a folder to hold various Git repositories (personal preference here after

    Use of the ~/gmail_acct folder is the result of setting up my Mac according to the automation and instructions at my https://wilsonmar.github.io/git-config

  2. Pull down from GitHub (assuming you’ve installed a git client program):

    cd ~/gmail_acct git clone https://github.com/wilsonmar/golang-samples

    PROTIP: Go source code files exist within a folder of the same name and have a suffix of .go.

  3. Navigate inside the folder created by the above command:

    cd golang-samples
  4. Get the present working directory path:


Workspace folders

Generally a Go workspace is created for each project, with three sub-directories:

  • src folder contains Go source code UTF-8 files with “.go” ending. Under this folder is the github.com or other such folder and the account name and repo name cloned by a go get command.

  • pkg folder contains compiled Go ‘dependency’ package objects referenced in imports within the source code. Such files are under a folder for its machine architecture (such as “darwin_arch64”). Each package object named (such as “package-name.a” for archived) contains the compiled package binary code, along with debugging symbols and source information. These files are created by the Go pack tool (compiler) while building/installing a package. Go uses packages here instead of the default packages folder $GOROOT/src or $GOPATH/src directories.

  • bin folder contains compiled executable packagess created by the go install command which trigger a go build (compile) command. The $GOBIN environment variable points to this folder as well as $GOPATH/bin. The default installation directory on macOS is /usr/local/go.

  1. Open a text editor to edit (~/.bash_profile on Macs) to:

    export GOHOME="$HOME/gmail_acct/golang-samples"

    Note that “gmail_acct” folder is the result of setting up my Mac according to the automation and instructions at my https://wilsonmar.github.io/git-config

    Alternately, append the file by using this command:

    echo “export PATH=$PATH:/usr/local/go/bin” » ~/.bash_profile

  2. Run .bash_profile:

    source ~/.bash_profile
  3. Navigate to the default home folder to see it work:

    cd $GOHOME

Instead of git clone

Use the equivalent of “git clone” to download slides and code to the “Testing in Go” video class by Brian Ketelsen:

    `go get github.com/bketelsen/testingclass`

The command above sends files to the $GOPATH folder path:
/Users/wilson_mar/gopkgs which is $HOME/gopkgs
$HOME/gopkgs/src/github.com/bketelsen/testingclass folder.

$GOPATH by default points to the $HOME/go directory in UNIX and %USERPROFILE%\go on Windows.

Hence, it is not absolutely necessary to setup GOPATH environment variable.


Source Code Editors

Unlike C#, Go is not associated with an IDE such as C# being associated with Microsoft Visual Studio or Java being associated with Eclipse and IntelliJ.

  • when using IntelliJ, put .idea in your project’s .gitignore file.

GoLand was built especially for the Go language, from JetBrains, for $80 after a 30-day trial. Install using

brew install --cask goland

However, shortcuts and reformat for Go are provided for text editors:

### Working with VSCode

  1. Install the free VSCode using Homebrew (instead of downloading from https://code.visualstudio.com):

    brew install --cask visual-studio-code

    NOTE: Installing with brew enables you to upgrade by simply:

    brew upgrade --cask visual-studio-code
  2. Open the app where the above installed the executable:

    open "/Applications/Visual Studio Code.app"
    NOTE: The app can be deleted by deleting that .app file.
    ### VSCode extensions
    PROTIP: To write better code and make formatting/debugging easier, install the VSCode extensions:
  3. In VSCode, click the gear (“Manage”) icon at the bottom of the left menu, then select “Extensions” (or press Shift + control + X).
  4. Type “Go” in the extensions search bar.
  5. Click on the one by “Go Team at Google” (formerly “lukehoban”) described as “Rich Go language support for Visual Studio”. The “M” says it has been downloaded millions of times.
  6. Click “Install” when it comes up on the right pane.
  7. Press command+Q to Quit the app entirely.

    App icon from Finder to Sidebar

  8. Switch to Finder. Navigate to your /Applications folder.
  9. Drag the “Visual Studio Code.app” file to the edge where the Toolbar resides, and drop it.

    This is so you can using a mouse to quickly invoke VSCode.

  10. In VSCode, click on “”
  11. In Finder, n to the “golang-samples” repository downloaded from above.
  12. Right-click on file challenge.go and select Open With, “Visual Studio Code”.
  13. In VSCode,

    Language recognition

  14. Open the app again.
  15. Install “Go for Visual Studio Code”.
  16. Install “Go Test Explorer for VS Code”.


  17. Bring up the Command Pallet by pressing Shift + command + P.
  18. Type “Shell”
  19. Click “Shell Command Install ‘code’ command in PATH.

    REMEMBER: Folder in variable GOROOT=”/usr/local/opt/go/libexec” is where downloaded packages install Go.

  20. To work with Go https://github.com/golang/vscode-go (formerly https://github.com/Microsoft/vscode-go)


    TODO: https://github.com/github/super-linter

    Component vulnerability scans

  21. Install JFrog Visual Studio Code extensions which reveals in JFrog’s GoCenter online security-related metadata about each reference in your go.mod (modules) files. After installation, “JFrog:” appears at the lower-right corner with a checkmark.

  22. The XRay Software Composition Analysis Tool (SCAT) is based on over 200,000 vulnerabilities identified and codified by Risk Based Security [RBS] in its VulnDB vulnerability database. It displays indirect (transitive) dependencies, in a hierarchical tree view.

  23. TODO: Install secret scanner.

On-line Go editor Playground

PROTIP: Like Python has “Pythonic”, “Gothic” is the adjective identifying idiomatic Go code (the easiest and most common ways of accomplishing a task using native language constructs rather than porting assumptions from a different language). See the “Idiomatic Go” blog by Dmitri Shuralyov (@dmitshur), who wrote githubv4 client library for accessing GitHub GraphQL API v4.

  1. VIDEO “Introduction to the Go Programming Language” course by Jeremy Cook at Go version 1.13 has a link to code for each sample at https://github.com/cloudacademy/godemo and:


  2. See his simple “hello-world” at


  3. View sample Go program source code containing basic coding constructs in an on-line editor at:


    Repeated below is that code:

    // hello.go at https://play.golang.org/p/0Hz57BQdTA
    package main
    import( "fmt"; "time"; "os"; "errors"; "math")
    var now = time.Now()  // wall clock to tell time
    func circleArea(radius float32) (float32, error) {
     if radius < 0 {
         return 0, errors.New("radius should be positive value")
     } else {
         return math.Pi * radius * radius, nil
    func main() {
     start_pgm := time.Now()   // monotonic clock to count time
     fmt.Printf("%s starting at %v \n", os.Args[0], now)
        argLength := len(os.Args[1:])
     if argLength == 0 {
         fmt.Printf("Arg length is %d \n", argLength) 
     } else {
         for i, a := range os.Args[1:] {
             fmt.Printf("Arg %d is %s\n", i+1, a)
         // TODO: carry out flags specified
     if area2, err := circleArea(-3); err != nil {
     } else {
     defer func(msg string) {
         if r := recover(); r != nil {
             fmt.Println("Recovered from panic.")	
     t := time.Now()
     elapsed_pgm := t.Sub(start_pgm)
     fmt.Printf("Done. Elapsed: %v\n", elapsed_pgm)

    // specifies an in-line comment for the compiler to ignore but humans to read.

    package main reflects that its file name is main.go, the first file which Go invoked within a folder.

    import has semi-colons separating modules.

    Variables defined outside a function have global scope (any function can reference it). var function takes in a pointer and stores the flag there, whereas, non-var functions return a pointer that can be stored and used.

    Functions return a tuple of two values: the result of calculations (in float32 data type) and an error string.

    if area2 is a sample numeric calculation function to show defensive programming.

    main() is the entry point for all Go programs.

    PROTIP: Code if/then/else statements to issue error immediately after the if statement.

    \n escape character n adds a new line break so several print outputs don’t run on together.

    Monotonic clock is not subject to clock synchronizations.

  4. Click “Run”.

    The response is the default time format as of the time run:

    /tmpfs/play starting at 2020-07-04 22:27:22.30492 -0600 MDT m=+0.000169133

    The above is the standard output format of the default time.

    Unlike Python, Go’s default time functions are timezone aware.

    But alas, the Go standard library does not contain localized month, day and zone names.

  5. func( defines an anonymous function to ensure a normal return code from the run.

    defer ensures that the function occurs regardless of the execution path around it. See https://blog.golang.org/defer-panic-and-recover

    Termianl program

  6. Let’s look at another program which uses flags:

    // USAGE: go run sample.go add -a=42 -b=23
    //        go run sample.go mul -a=25 -b=4

    Usage defines examples of how to call this program using flags

Who uses Go?

Although unveiled in 2009, companies who have adopted Go in their products include Atlassian, Docker, Facebook, DigitalOcean, Cloudflare, eBay, Heroku, Hashicorp, Capital One.

PROTIP: The canonical list of companies using Go is at

A 2016 survey found that 40% of respondants used the language for less that 1 year.

When asked what they like most about Go, users most commonly mentioned Go’s simplicity, ease of use, concurrency features, and performance.

What changes would most improve Go? Users most commonly mentioned generics, package versioning, and dependency management. Other popular responses were GUIs, debugging, and error handling.

Other Sample Source Repositories

There are many good examples of Go programming code on the internet. Among the better-known repositories to consider:

  1. My own collection of example code is private. Contact me to be a collaborator.

  2. Download or git clone


  3. Open a Terminal shell window and give the files execute permissions:

    chmod 555 * 

    hello-time.go template

  4. cd to hello-time, which I use as the basis for creating new files.

    • print the elasped time of the program run.
    • define a date
    • calculate days from hours
    • format dates based on a template
    • see https://coderwall.com/p/l7e3fq/golang-time-function-wrapper

  5. A line at the top of the file enables it to be optionally run as a shell sript:


  6. Run it as a program:

    go run hello-time.go

    Build executables

  7. Build it

    go build

    A file with no file extension should appear in the folder on Linux. Extension .exe is added on Windows machines.

    When compiling packages, build ignores files that end in ‘_test.go’.

    To build an executable for running on other operating systems:

    GOOS=openbsd go build
    GOOS=windows GOARCH=386 go build
  8. PROTIP: Ensure that executable created are excluded from being uploaded to GitHub by an entry in .gitignore:


    Executables should be stored in artifact repositories such as JFrog Artifactory, AWS CodeArtifact, etc.

  9. Run the executable on Linux or mac:


    Alternately, on Windows, run the executable:


    PROTIP: All Go programs must be part of a package. main is the default package.

    • Global variable - start time.
    • Four character indent. gofmt indents using tabs that take 8 characters.

    Run program with flags

    ./program -a=b -c=d

Test-Driven Development (TDD)

PROTIP: When you create a new go source file, also create a companion _test file* for “black box” unit testing of each function:


Within the _test.go file, for example:

package messages
   func TestAdd(t *testing.T) {
    a := 1
    b := 2
    expected := 3
    actual := Add(1,2)
    assert.Equal(t, expected, actual)

Test begins the name of every test function so that you can name specific tests in command such as:

t.Helper method flags methods to skip a test.

go test Add

The assert statement from importing testify eliminates two lines and repetitive text.

    if expected != actual  {
        t.Errorf("Result was incorrect, got: %d, want: %d.", actual, expected)

t.Name reflects the name of the test in messages.

t.Log and t.Logf outputs a message without setting result status.

The “f” as in t.Logf and t.Errorf and t.Fatalf specifies formatted use of %v for strings. Like other printf functions, an escaped new line \n is needed.

t.SkipNow skips the test with no message. t.Skip outputs a string. t.Skipf outputs with variables.

t.FailNow() takes no arguments and doesn’t issue a message when it stops immediately. t.Log, t.Error after t.Fail are ignored.

t.Error, and t.Fatal are different levels of severity. Error is Log followed by t.Fail.

t.Error and “t.Errorf” fails out (and stops) on error.

t.Error* continues on error (non-immeidate failures).

PROTIP: Using assert statements with variables enable you to copy and paste and code less. This also makes it more readable.


t.Cleanup registers a function (meaning it won’t do it right away).

t.RunParallel is added for faster runs.

  1. To list coverage of unit tests defined:

    go test -coverage
  2. Table:

    func TestAddTableDriven(t *testing.T){
    scenarios := []struc {
        input string
        expect string
        {input: "Gopher", expect: "Hello\n"},
        {input: "", expect: "hello\n"},
    for _. s := range scenarios {
        got := Greet(s.input)
        if got != s.expect {
            t.Error("Did not get expected $v", 
               s.input, got, s.expect)

TDD and other techniques

https://github.com/gavv/httpexpect for testing over the network

https://github.com/onsi/ginkgo for BDD-style developement.

https://code.google.com/p/gomock to mock calls.



Vendor prior to Modules

When Go was first released, it provided no mechanism to manage different versions. Vendoring was the first system supported by the Go Core team. In Go 1.12 and before, Go looks in the “vendor” folder before looking in GOPATH for a stated import.

New module

CAUTION: Avoid importing modules from sources you don’t know if you can trust.

import {
   . "github.com/bmuscho/go-testing-frameworks/calc"
  1. Create a new module:

    go mod init github.com/mememe/godemo

    This creates a README.md file, a main.go, folders math and util.

    The go.mod file

    NOTE: https://github.com/rogpeppe/gohack makes it easy to Make temporary edits to your Go module dependencies.

  2. Generate checksums in go.sum file:

    go get
  3. Verify the integrity of modules by running checksums again and comparing results against the go.sum list of hashes:

    go mod verify

    The expected response is:

    all modules verified

  4. Identify the latest version of dependencies:

    go list -u -m -all
  5. Change the go.mod file:

    go mod tidy

Auto format code

PROTIP: Many developers type code from the first character because they let formatters automatically take care of proper indentation.

  1. Format source code according to Go coding standards using the standard format “fmt” (PROTIP: pronounced “fmpth”)

    go fmt ./…


    Go is a tool for managing Go source code.
         go  [arguments]
    The commands are:
         bug         start a bug report
         build       compile packages and dependencies
         clean       remove object files and cached files
         doc         show documentation for package or symbol
         env         print Go environment information
         fix         update packages to use new APIs
         fmt         gofmt (reformat) package sources
         generate    generate Go files by processing source
         get         download and install packages and dependencies
         install     compile and install packages and dependencies
         list        list packages or modules
         mod         module maintenance
         run         compile and run Go program
         test        test packages
         tool        run specified go tool

    The three dots specify recursion down the current folder.

    Alternately use the formatter from https://golang.org/cmd/gofmt/”> which has flags for more control:

    go gofmt -s -d -w main.go

    -w saves the changes.

    . (dot) instead of the main.go would recursively process.

    go gofmt ./..

    To reformat within VSCode ???

  2. Identify unreachable code with static analysis:

    go vet ./..


  3. Install and configuring goimports to automatically run on save to format and auto adjust import statements as needed:

    go get code.google.com/p/go.tools/cmd/goimports

    BLAH: I’m getting these messages:

    package code.google.com/p/go.tools/cmd/goimports: unrecognized import path "code.google.com/p/go.tools/cmd/goimports" (parse https://code.google.com/p/go.tools/cmd/goimports?go-get=1: no go-import meta tags (meta tag github.com/golang/go did not match import path code.google.com/p/go.tools/cmd/goimports))
  4. Setup vim to auto run goimports on save using vim-go:

    let g:go_fmt_command = "goimports"

    BLAH: Response is “-bash: let: g:go_fmt_command: syntax error in expression (error token is “:go_fmt_command”)”

  5. Setup reload web server when file change is detected:



    https://github.com/gin-gonic/gin “Gin” web framework

    Tour of Language Syntax

  6. Tours of Go language syntax are presented on these websites:

Packages Imported

Go was created with a rich set of packages built-in in its standard library.

  1. Get a list of them:

    go list std

    Path of Packages in $GOPATH

    In the code, an alternative way to specify 3rd-party libraries:

import (

If you get error message “cannot find package” when running a go program:

NOTE: Go looks for packages first within the folder where you installed Go. If you installed using Homebrew, that would be like:


(from $GOROOT)

PROTIP: Don’t install packages under where Go is installed. This is so you won’t have problems after you upgrade to the next version.

  1. Create a $HOME/gopkgs folder to store 3rd party Go packages in one place.

    cd ~
    mkdir gopkgs
    cd gopkgs

  2. Create a $GOPATH environment variable to store a list of folders containing Go programs, separate by semicolons. In my ~/.bash_profile:

    export GOPATH=$HOME/gopkgs

    There can be a list in the path, separated by colons in Linux/Mac. Go searches each directory listed in GOPATH to find source code.

    CAUTION: New packages are always downloaded into the first directory in the list.

    See https://golang.org/doc/code.html#GOPATH

  3. Close Terminal and start it again, or

    source ~/.bash_profile

  4. Get a package from below. For example:

    go get github.com/stretchr/testify

    go get does the equivalent of cloning a package repo from GitHub. The manual equivalent of that is:

    git clone https://github.com/stretchr/testify --depth=1

    Alternately, other libraries to get:

    go get -v https://github.com/golang/example

    PROTIP: If nothing is returned and you get the prompt again, that’s a good thing.

  5. Look within src is created a github.com folder.

    ls ~/gopkgs/src/github.com

    If there isn’t one, Go will have created a src folder.

    NOTE: The pkg folder holds installed package objects, such as “linux_amd64”.

    NOTE: Other “collaboration platforms” like GitHub include:

    • launchpad.net
    • bitbucket.com
    • gitlab.com

  6. For each 3rd-party library is created a folder for each GitHub user. For example, stretchr.

    cd ~/gopkgs/src/github.com
    mkdir stretchr
    cd stretchr

  7. Compile to binary executables all files in current folder to $GOPATH/bin :

    cd $GOPATH
    go install .

Install apps

To install the Go package for reading from continously updated files (tail -f)

go get github.com/arschles/go-in-5-minutes/tree/master/episode0
  • PROTIP: There is no “http://” in front of github.com when getting go packages.

  • This repo is described in videos at goin5minutes.com. Aaron Schlesinger, Sr. Software Engineer at EngineYard, describes how to write Functional Programming in Go for real projects.




For better, many prefer to use only stdlib features.

The most popular packages for Go as found searching through all of GitHub:

  1. https://github.com/stretchr/testify/assert A “sacred” extension to the standard go testing package

  2. https://github.com/gorilla/mux provides mux.Router which, like Go’s in-built http.ServeMux, matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions. “Mux” stands for Multiplexor, to multiplex routes (URLs) to different handlers. Routers are also called dispatchers. This article says install using

    brew install go --cross-compile-common
    go get -u github.com/gorilla/mux

    The Gorilla mux allows devs to really lock down an API.



  3. github.com/Sirupsen/logrus by Simon Eskildsen @shopify
    Structured, pluggable logging for Go.

  4. github.com/gorilla/context
    A golang registry for global request variables.

  5. github.com/golang/protobuf/proto ???

  6. github.com/urfave/cli, formaerly
    A simple, fast, and fun package for building command line apps in Go.

  7. github.com/mattn/go-sqlite3
    sqlite3 driver for go that using database/sql

  8. github.com/go-sql-driver/mysql
    Go MySQL Driver is a MySQL driver for Go’s (golang) database/sql package

  9. github.com/BurntSushi/toml
    TOML (Tom’s Obvious, Minimal Language) parser for Golang with reflection. https://github.com/toml-lang/toml

  10. github.com/garyburd/redigo
    Go client for Redis

  11. github.com/golang/glog
    Leveled execution logs for Go

  12. github.com/onsi/ginkgo by Onsi Fakhouri @ Pivital
    BDD Testing Framework for Go http://onsi.github.io/ginkgo/

  13. github.com/onsi/gomega
    Ginkgo’s Preferred Matcher Library

  14. github.com/juju/errors at Ubuntu Canonical
    Common juju errors and functions to annotate errors. Based on juju/errgo. Model and deploy applications to any cloud

  15. github.com/juju/testing/checkers
    provides additional base test suites to be used with gocheck. Testing gocheck suites and checkers used across juju projects.

  16. github.com/stretchr/testify/assert and mock
    are libraries to test interfaces and API functions using easy assertions, mocking.

  17. https://pkg.go.dev/go.opencensus.io/?tab=doc
    contains Go support for OpenCensus. https://opencensus.io/exporters/supported-exporters/go/ https://opencensus.io/introduction says OpenCensus makes getting critical telemetry out of your services easy and seamless. It provides libraries for a number of languages to capture, manipulate, and export metrics and distributed traces to the backend(s) of your choice – from client applications, large monoliths, or highly-distributed microservices. OpenCensus started at Google but is now developed by a broad community of service developers, cloud vendors, and community contributors. OpenCensus isn’t tied to any particular vendor’s backend or analysis system. vs. Prometheus


  18. github.com/mitchellh/go-homedir
    go-homedir homedir.Dir() detects the user’s home directory without the use of stdlib os/user cgo, so the library can be used in cross-compilation environments.

  19. github.com/pierrec/lz4
    provides a streaming interface to LZ4 data streams as well as low level compress and uncompress functions for LZ4 data blocks. The implementation is based on the reference C one.

  20. Julien Schmidt’s high performance replacement of stock HTTP request router at
    is a trie based.

  21. github.com/cenkalti/backoff
    is a Golang port of the exponential backoff algorithm from Google’s HTTP Client Library for Java. It uses feedback to multiplicatively decrease the rate of some process in order to gradually find an acceptable rate. The retries exponentially increase and stop increasing when a certain threshold is met.

  22. github.com/davecgh/go-spew/spew
    Go-spew implements a deep pretty printer for Go data structures to aid in debugging.

  23. github.com/jmespath/go-jmespath
    JMESPath is a query language for JSON, to transform one JSON document into another JSON through a JMESPath Search expression.

  24. github.com/mitchellh/mapstructure
    mapstructure is a Go library for decoding generic map values to structures and vice versa, while providing helpful error handling. It’s for decoding values from data streams (JSON, Gob, etc.) where you don’t quite know the structure of the underlying data until you read a part of it. You can therefore read a map[string]interface{} and use this library to decode it into the proper underlying native Go structure.

  25. github.com/stretchr/objx
    Objx - Go package for dealing with maps, slices, JSON and other data.

Internationalization? Not Yet

The Golang StdLib golang.org/x/text/language, message, etc. does not fully support I18N (at time of writing). A proposal describes golang.org/issue/12750 remains Open.

So although extensive, many have found the documentation lacks clarity and the library difficult to use. Marcel van Lohuizen (@mpvl) worked on it alone on a 50% basis at Google Vienna. VIDEO: In 2017 he was working on date localization, with bidi (bi-directional) and gender in the future.

  • https://blog.golang.org/matchlang
  • https://github.com/qor/i18n

https://github.com/nicksnyder/go-i18n by Nick Snyder is an easier way to localize Go apps. It supports (with good documentation):

  • Pluralized strings for all 200+ languages
  • Strings with named variables
  • Implements CLDR plural rules.
  • Uses text/template for strings with variables.
  • Translation files are simple JSON.
  • Message files of any format (e.g. JSON, TOML, YAML, etc.).
  • Code and tests are automatically generated from CLDR data.

However, go-i18n (at time of writing) does not support gender rules or complex template variables.


VIDEO: “Internationalization is a Piece of Cake” by Eli Schutze Ramirez CLDR (Unicode Common Locale Data Repository) contains all aspects for each BCP47-defined locale. ICU provides a wrapper to CLDR. Do not build sentences yourself. Let the program arrange word order to the locale.

Pave Loborin’s repo shows (in Russian) how to use the Sprintf function to translate for localization.

Instead of ICU is still not powerful enough.



Security Vulnerabilities

All the CVEs (Common Vulnerabilities and Exposures) reported for Golang into the NVD (National Vulnerability Database). Each CVE may be linked to a CWD (Common Weakness Enumeration) within underlying code such as cwe-444.

Social #golang

Go users call themselves Gophers. Thus the logo.

Social Communities


@GopherCon - https://gophercon.com/ - July 13-15, 2017 in Denver, Colorado


Rock Stars’ emissions

The Go language was invented within Google
by Robert Griesemer and Unix luminaries Rob Pike and Ken Thompson.[1]


  • https://talks.golang.org/2014/taste.slide#2

Rob Pike (Go Commander, Google)

TJ Holowaychuk is perhaps the most visible defector from Node, as he wrote Node. See https://goo.gl/WVxwtb

Russ Cox

Todd McLeod presents his deep knowledge in a laid-back style so it’s like listening to him at a party:

Mike Van Sickle (@vansimke)

Mark Summerfield [1]

  • Book: Programming in Go: Creating Applications

Dave Chaney

  • https://dave.cheney.net/resources-for-new-go-programmers

  • https://talks.godoc.org/github.com/davecheney/introduction-to-go/introduction-to-go.slide#1

  • https://github.com/davecheney/introduction-to-go

Francesc Campoy

  • Google Developer Advocate
  • https://talks.golang.org/2017/state-of-go.slide#1
  • Understanding nil

Nic Raboy

Brian Hatfield

  • @BrianHatfield

  • Tweets about GC pause times

William Kennedy

Free Tutorials

https://learn.go.dev (“Go, Getting Started”)







API SDK Server Frameworks

On web servers, many Go gurus say just use sub-routers using stdlib net/http instead of encapsulating all routing decisions into one single component using <a target="_blank" href="https://godoc.org/net/http#ServeMux">http.ServeMux</a> or Not even <a target”_blank” href=”https://github.com/julienschmidt/httprouter”>httprouter</a>

Some like Echo at echo.labstack.com. Some resources on Echo:

### For Multiple Operating systems

  1. View multi-platform.go

  2. Build for macOS

    go build
  3. Build for Windows

    GOOS=go GOARCH=amd64 go build -o godemo-win-amd64.exe . 
  4. List the platforms (GOOS/GOARCH):

    go tool dist list

    Random number generator

  5. rand.go

    • Import flag to obtain arguments from command line
    • Reflection of elasped time is not appropriate here because it is intended to run as a utility.
    • Defined in a main plus separate utility functions.
    • Loop the number of repeats specified.
    • Slice of an integer array containing prime numbers. See https://tour.golang.org/moretypes/8 Notice there can be a ending comma after the last item in the list. This avoids one of the most annoying error messages in other languages.
    • Pointer

    Loop until manually stopped

    Within a main infinite loop:

    func main() {
      var input string
      for {
  6. switch

    • Print command to construct a line printed over several command lines
    • Recognize operating system being used by using “runtime.GOOS”.
  7. strings

    • One Println with several commands.
  8. latlong

    It manages latitudes and longitudes in a map data type containing a key-value structure.

    • Uses float64 floating point number for latitude/longitude
    • Uses function to do repeated lookups
  9. utf8

    It provides examples of counting and comparing Asian characters encoded in UTF-8.

    • Provides an illustration of fmt.Print() vs. fmt.Println() with escapted double-quotes.
    • Provides an example of using range.
  10. cd to env-vars (in Git branch env-vars)


    Different Operating Systems

Structure of program files


Data Types

boolean constants are lower case: true, false

Numbers are not permitted at the start of an identifier (variable).

Go detects unused imports as an error.

Go has an array type, but most interactions are with slices which are built off arrays. I don’t worry too much about the name and just use them The specification for slices are “[]T” where T is the type. So “[]string” is a set of strings, “[]int” is a set of integers, and so on.


var n int = 4
var i = 0
for i = 1; i < n; i++ {

int is actually an alias! Like C, Go has signed and unsigned integers:

  • int holds a maximum value of 32,000.
  • int8,
  • int16,
  • int32,
  • int64

UTF-8 Data Types

Alias rune are single-character constants: ‘a’, す’, ‘シ’, ‘1’, …

When working with unicode you should be converting your strings to []rune. That’s why the utf8 package is so sparse, most things are covered by []rune conversion and the unicode package. The utf8 package is like a very thin abstraction layer for using strings as []rune.

All source code in Go is UTF-8, so you can use an emoji, Japanese Kanji, or other language in variable names:

    var π = 3.14159
    var radius = 6371.0 // radius of the Earth in km
    var circumference = 2 * π * radius
    println("Circumference of the earth is", circumference, "km")

Run result in scientific notation:

   Circumference of the earth is +4.003014e+004 km

See https://coderwall.com/p/k7zvyg/dealing-with-unicode-in-go

Developer Tools

  1. Display documentation for the Println function within fmt:

    godoc fmt Println

    Println formats using the default formats for its operands and writes to standard output. Spaces are always added between operands and a newline is appended. It returns the number of bytes written and any write error encountered.

Code Quality Scanner


golint for “code smells”

go vet to identify nonsensical code.


Google’s shenzhen-go is a Visual Go environment

Unit testing

  1. PROTIP: Get to know about all the different ways to invoke go test:

    go help testflag

  2. Install the Go Present tool:

      `go get golang.org/x/tools/cmd/present`

    cd testablecode/freemail

  3. Run all internal tests defined in the current folder:

    go test -v -run=G

    The response for a single method invoked shows the time it took to run:

    === RUN   TestGmail
    --- PASS: TestGmail (0.00s)
    ok      github.com/bketelsen/testingclass/testablecode/freemail 0.637s

    -v sets the verbosity mode to “verbose”.

    -run=G runs tests based on pattern matching the letter “G” in the test name “TestGmail”.


Table-driven tests


“External” Tests are in a separate package (scope) than the code being tested, such as in documentation. External test names are suffixed with “_test”. Due to its external nature, identifiers must be prefixed by the package identifier.

Acceptance Testing

Agouti is an acceptance testing framework for Go.


backtrace.io/go/ Reduce your time to resolution. Go beyond stacktraces and logs. Get to the root cause quickly with deep application introspection at your fingertips.





https://github.com/influxdata/semaphore Distributed semaphore for Etcd in go forked at https://github.com/influxdata/semaphore



Web server

https://cloudacademy.com/lab/using-marathon-to-schedule-mesos-containers-on-dcos/creating-golang-web-application-binary/”>Video course: Using Marathon to Schedule Mesos Containers on DC/OS Creating a Golang Web Application Binary</a>

https://github.com/GoesToEleven/golang-web-dev contains code for Tood McLeod’s WebDev class for Go at GreaterCommons.com.



A static web server to serve Jekyll generated static files:

// From https://coderwall.com/p/up2jbg/golang-static-files-server
package main
import "net/http"
func main() {
    http.Handle("/", http.FileServer(http.Dir("_site")))
    err := http.ListenAndServe(":8000", nil)
    if err != nil {

Profiling Go Code




flame graphs

go test -coverprofile

Output a cover profile as you are testing a package, then use go tool to visualize them on a browser.

go test -coverprofile=c.out && go tool cover -html=c.out


go test -bench=.

https://newrelic.com/golang monitor

Protocol Buffers (Protobuf)



### Webpage folder templates

  1. In webpage, main.go uses a templating capability with mustache markers:

    \{{{/* comments don't nest */}}
    • Display a line before running as a server which locks no command line input:
    fmt.Println("Use internet browser to view localhost:8080.")
    fmt.Println("Press control+C to stop server.")
    http.ListenAndServe(":8080", nil)

Code Generators

https://github.com/erizocosmico/go-itergen by Santiago M. Mola (@mola_io) generates Go source files

https://godoc.org/text/template Go Package Templates use double moustache pairs {{ {} around variables.


https://github.com/uartois/sonar-golang Sonarqube plugin for the golang language created by Falque Thibault with 34 rules from GoLint.

https://github.com/qfarm/qfarm Sonar for Golang - PoC created during 24h hackaton



Machine Learning

https://github.com/sjwhitworth/golearn reads a databse of iris flowers, as KNN (Nearest Neighbor) makes predictions using the training dataset directly. k is just the number of neighbors “voting” on the test example’s class. See http://machinelearningmastery.com/k-nearest-neighbors-for-machine-learning/

Impose Artificial Load

https://github.com/rakyll/hey consists of two utility Go programs used to impose load on servers by making HTTP and HTTP/2 requests.

The program is influenced from Tarek Ziade’s tool at tarekziade/boom.

It was written by Google for use in its Google’s Scale and Load Balance Instances and Apps tutorial.

To send 10 requests per second to the load balancer (substituting your load balancer’s external IP):

hey -n 12000 -c 10 -q 1 http://load-balancer-IP

Additional arguments enable HTTP headers to set authentication data, etc.

Monitoring is achieved by other means.


https://github.com/google/go-github Go library for accessing the GitHub AP




  • https://blog.gopheracademy.com great resources for Gophers in general
  • http://gotime.fm awesome weekly podcast of Go awesomeness
  • https://gobyexample.com examples of how to do things in Go
  • http://go-database-sql.org how to use SQL databases in Go
  • https://dmitri.shuralyov.com/idiomatic-go tips on how to write more idiomatic Go code
  • https://divan.github.io/posts/avoid_gotchas will help you avoid gotchas in Go


  • http://www.golangbootcamp.com/book
  • http://gopl.io/
  • https://www.manning.com/books/go-in-action (if you e-mail @wkennedy at bill@ardanlabs.com you can get a free copy for being part of this Slack)


  • https://www.slideshare.net/appleboy/write-microservice-in-golang





Other tutorials

https://github.com/golang-samples/gopher-vector has gopher cover art.


Hacker News


@GopherAcademy - gopheracademy.com

https://changelog.com/gotime podcasts

@cool_golang is a bot that automatically retweets any mention of #golang on Twitter.


@gophersauce - Golang backend web framework #golang #go checkout. “The easiest App SDK in the world.” https://github.com/cheikhshift/Gopher-Sauce/blob/master/tutorial.md

William Kennedy, author of blog GoingGo.Net, created “Ultimate Go Programming, Second Edition” (September 2018) containing 15 hours of videos in a “Top Gun” course for experienced Go developers. He covers Language Syntax, Data Structures, Decoupling, Composition, Error Handling, Packaging, Data Races, Channels, Concurrency Patterns, Testing, Profiling and Tracing. He also co-wrote Go in Action (Manning)

https://event.on24.com/eventRegistration/console/EventConsoleApollo.jsp?&eventid=2199520&sessionid=1&username=&partnerref=&format=fhvideo1&mobile=false&flashsupportedmobiledevice=false&helpcenter=false&key=3FAF1CE28FC4FBF4F1B37E0A77625BB4&text_language_id=en&playerwidth=1000&playerheight=650&overwritelobby=y&newConsole=false&nxChe=true&eventuserid=325676257&contenttype=A&mediametricsessionid=278102792&mediametricid=3108609&usercd=325676257&mode=launch# https://github.com/bmuschko/testing-go-projects/ Benjamin Muschko (bmuschko)

https://quii.gitbook.io/learn-go-with-tests/ Learn Go with Tests




Go in Google App Engine


Google App Engine is a serverless compute platform that is fully managed to scale up and down as workloads demand. Cold Start (zero instances running) request initial response times are often between 80 and 1400 milliseconds. Hot (at least 1 instance running ) requests are fulfilled immediately.

Google Qwiklabs “Getting Started with Go on Google Cloud” has 5 steps:

  • “Use Go Code to Work with Google Cloud Data Sources” (BigQuery SQL of Calif zip codes and Firestore document db collection called symbols of sample retailer UPC and product information.) by the “GCP Data Drive” program from git clone https://github.com/GoogleCloudPlatform/DIY-Tools.git 1 hour 10 minutes, 5 Credits

  • Deploy Go Apps on Google Cloud Serverless Platforms. Use GO (golang) to deploy an app on App Engine, Cloud Run, and Cloud Functions using Cloud Build. 1 hour 10 minutes, 5 Credits

  • App Engine: Qwik Start - Go. Create a small App Engine application that displays a short message. Watch the short video Build Apps at Scale with Google App Engine. 20 minutes, 1 Credit

  • HTTP Google Cloud Functions in Go, 30 minutes

  • Quiz: Getting Started with Go

Go Tutorials

Stephen Grider (ste.grider at gmail) created his highly-rated Udemy “Go: The Complete Developer’s Guide (Golang)” in 2017 and has kept it maintained. It contains 9 hours of videos. Code (edited using VSCode) and diagrams for the course are at https://github.com/StephenGrider/GoCasts. Within each numbered folder, click on its diagrams.xml file, then “Raw” button for its URL.


In https://www.draw.io, for “Save Diagrams To…” click “Decide later”. Click menu File, Import From, URL. Paste the link. Press Enter (click Import) for the diagram to appear. Click on the tabs at the bottom of the window. You can then save the file. Click File, Close, Discard changes. For the next file, change the chapter number in the URL and repeat this paragraph of steps.

Jon Calhoun of https://www.calhoun.io/courses

BOOK: “Let’s Go” by Alex Edwards

PODCAST: Creating a Video Course Hosting Platform to Learn Go by Jon Calhoun at https://www.calhoun.io/courses