Get Going With Go - Brown University

CS1380

Distributed System

Theophilus Benson

Get Going With Go

Spring 2021

Contents

1 Introduction

1.1 About Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

2

2 Installation

2.1 Go Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

2

3 Code Organization

3

4 Learning Go

4.1 Standard Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4.2 Getting Help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

4

5

5 Building and Running

5

6 Testing and Benchmarking

6.1 Benchmarking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6.2 Checking Test Coverage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

6

6

7 Recommended Tools

7.1 gofmt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7.2 godoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7.3 IDE Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7

7

7

7

CS1380

1

Distributed System

Theophilus Benson

Introduction

Welcome to CS 138! This guide will get you started with the programming language Go. Well

go over getting setup (which can be a little tricky), organizing your code, formatting it, building

and running it, as well as useful plugins for your favorite editors and IDEs.

We highly recommend getting set up correctly with Go before beginning on the assignments.

Also, while this is a relatively long guide, dont feel like you have to read it all in one sitting.

Treat it more like a reference document!

1.1

About Go

Go is an open-source programming language created by a team at Google (and other outside contributors). Go was initially started in 2007 by Robert Griesemer, Rob Pike, and Ken Thompson.

Go is a systems language with roots in C, C++, and other languages. Version 1 of Go was released

in 2012 and is under active development (v1.7 was released in August 2016). If you have more

questions about Gos history theres a wonderful FAQ on their website which we urge you to check

out.

2

Installation

The department machines already have Go installed as a contrib project (v1.13) at /contrib/bin/go1.13,

but in case you want to use your own machine, you can follow the official installation directions.

Note that the department machines also have go 1.7 installed, but this course uses 1.13. If you

want to run go commands on the department machine, you need to type go1.13 instead of just go.

If youre on a Mac and use the Homebrew package manager, you can simply run brew install go@1.13

to install that version (or just brew install go to install the latest versin).

If youre on Windows, this blog post by Wade Wegner is a great reference.

2.1

Go Modules

One of the hardest things for folks new to Go is structuring a Go project, as the Go compiler is

very opinionated about it.

In the past, Go required all Go projects on your system to be located under one folder, specified

by the GOPATH environment variable. The Go compiler would only build a project if source

code was in a folder under $GOPATH/src, would install external libraries and dependencies under

$GOPATH/pkg, and put compiled binaries under $GOPATH/bin.

In recent versions of Go, this dependence on GOPATH has been removed thanks to the advent of

Gos module systems (also called just Go modules). Further, the community has standardized on

one specific project layout structure that minimizes tensions. (Note that GOPATH is still used

by Go internally, but is usually just left at its default valu typically $HOME/go on Unix systems

and %USERPROFILE% on Windows).

At a very high level, the Go module system works by declaring your current folder a module. Modules can be thought of as virtual environments: they get their own private package management

system, and all Go dependencies are contained inside the module.

To create a new project using Go modules, go to any folder on your system.

First, pick a globally unique name1 for your module. Suppose you want to call your new module

1 It is typically a best practice to use the remote URL from which the project can be downloaded e.g. a module

might get named user/example. This is important because it allows other Go modules to download

your module. For self-contained Go code which will never be downloaded by other modules (which includes all the

CS1380

Distributed System

Theophilus Benson

example.

Next, run go mod init example. This will create a go.mod.

Lets open up our go.mod file:

module example

go 1.13

Congratulations, you have made a Go module!

Now you can attempt to fetch packages. Try running go get google.protobuf/cmd/protoc-gen-go.

This will install a Go package for you, making it available to your system to use. If you are familiar

with pip from Python or npm from Node.js, it is very similar.

You will note that your go.mod has now been updated and looks like:

module example

go 1.13

require google.protobuf v1.25.0 // indirect

Additionally, a file containing checksums for each downloaded package has been created at go.sum.

A tutorial on how to work with Go modules in more depth can be found here. In particular, we

recommend looking at four aspects of the module system:

? The go mod tidy command. This cleans up unused packages and downloads newly added

packages to the go.mod file (as you can manually edit that if you want to).

? You can control the package version of any package just by updating the version indicated

in the require statement. Versions are somewhat haphazardly baked into the system

version numbers resolve to Git tags on the remote URL for the repository, and you cannot

use version numbers with major version starting with 2 (owing to historical legacy). Go

version numbers follow versioning.

? The go clean -modcache command. This removes cached packages, useful if youve updated the version for an already downloaded package and want to pull it in.

? The replace directive. This is a very powerful feature that allows you to replace what a

module name gets resolved to. You would use the replace directive, for example, to point all

imports of foo to a local directory. This allows you to transparently shim any package, as a

way of trying out changes or behaviour. It is absolutely necessary when working with forks

of a repository, as often all the import statements are pointing to the original source and

you wish to avoid renaming all the statements (as some imports may depend on the source

of the fork transitively, by depending on a package that depends on it).

3

Code Organization

A repository of Go code can contain one or more packages:

? A package is a collection of related .go files, usually implementing one particular algorithm

or utility.

? Most packages are designed to be shared, and will be imported into other files. Within

packages, you can decide which types and functions are exported, meaning they will be

projects you will be working on in this class), any globally unique name is fine.

CS1380

Distributed System

Theophilus Benson

available to code written outside of this package. In contrast, unexported types and

functions are only available for use within the package.

? Code in the special package main is designed to be compiled into an executable binary,

usually a command-line program run by end users.

? Note that a project or repository can have several main packages. Each of them may exist in

different directories, and will compile to different binaries (named after the directory). This

is a common pattern in projects with multiple executables or CLI programs (client and

server, for example.)

? See the Building and Running section for information on building packages and binaries.

Additionally, there are some standards on how to structure any Go project:

? The top-level cmd/ folder is meant to house any main packages. You can have multiple

unrelated main packages in separate subfolders.

? The top-level pkg/ folder is meant to house packages used by other applications (such as

those in cmd/ or remote code) that is, public packages. Typically, you may put public

library code within this module anyone can download.

? The top-level internal/ folder is meant to house packages used only within the module

(including those in cmd/) that is, private packages. This folder is unique in that the

privacy is guaranteed by the compiler attempts to import code from another repositorys

internal folder will result in an error during compilation.

? Golang developers discourage the use of src/ folders. More standards are discussed and

found here.

Deciding when to put code within pkg/ or internal/ depends on your projects usecases and

needs. For all of the projects in this course, we have opted to place core code within pkg/, on the

premise that Go compiler restrictions on package imports are one less thing to worry about as you

learn to master Go real code in a real production setting may choose differently.

Note that in this class, for each project (except for Puddlestore) we provide the stencil code for

each runnable binary that you will want to generate. So you dont have to worry too much about

the structure of your packages and code, and can focus on implementing the systems we ask you

to implement.

4

Learning Go

The best way to pick up the basics of Go is to walk through the Tour of Go.

In particular, look out for the difference between slices and arrays (hint: you should almost always

use slices in Go), exported vs. unexported names, channels, and goroutines.

If you prefer a more hands-on approach to learning Go, the Go by Example series is a great set of

practical code examples in Go representing some of the languages unique features.

Current TAs of the class have had great results when learning Go by simply looking at the

corresponding example when they got to a part of the project code that required a particular

feature they hadnt seen before.

4.1

Standard Library

Once you get up-and-running with Gos syntax and actually start writing code, the most comprehensive reference for Gos standard library can be found here.

CS1380

Distributed System

Theophilus Benson

Every package, along with all of their functions and types are very well documented in these pages,

including type signature and a description of what each function and type does.

4.2

Getting Help

Links to the Go forums, mailing list, Slack, and FAQ can be found on the help page.

If you get confused about a particular function you come across in CS138, or if you need to find out

how to do something you havent seen before, you can always search for golang [your question].

Note that typing golang instead of go will usually give better results, since a lot of things on

the Internet are called go (like HBO Go!).

5

Building and Running

There are a few main commands you should be aware of to build and run Go code:

? go build

When you want to compile a main package into an executable (such as compiling your

CoinLite binary), navigate to the directory containing the main package, and run go build.

This will compile the binary, link any imports, and place the executable into your current

working directory.

When you want to compile a non-main package, navigating to the directory containing the

main package and running go build will compile all the files, link any imports, and exit

without any generated files. This is useful to see if your package compiles without errors or

warnings.

? go run

When you want to compile and quickly run a main package, but not save the resulting

binary executable, run it with go run ./path/to/file.go, where file.go is a file in the

main package.

? go install

When you want to compile a main package and add the generated binary to $GOPATH/bin

(which still exists even after using Go modules), run go install /path/to/main/package.

This means you can simply run the binary from anywhere, such as $ coinlite -mode ...

-addr ..., since the binary can be found from your $PATH.

? go 1.13

Remember, when you use go on the department machines, you need to explicitly refer to

go1.13 instead of just go. On the dept machines, go refers to go 1.7, which is not the version

this course uses.

You may also add alias go="go1.13" to /.bashrc so that you can refer to go1.13 simply

as go.

Usually, we recommend using go install while working on your projects. This is so that you

can compile and generate multiple binaries at once, and use them instantly from anywhere. For

instance, in a project that generates a binary for clients and a binary for servers, running go

install ./... (note the ellipsis) will build every main package Go can find in the current

directory downwards, and install them into $GOPATH/bin. Then you have immediate access from

anywhere on your machine to those compiled binaries.

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download