Learning Go
Learning Go
#go
www.dbooks.org
Table of Contents
About 1
Remarks 2
Versions 2
The latest major version release is in bold below. Full release history can be found here. 2
Examples 2
Hello, World! 2
Output: 3
FizzBuzz 3
GOPATH 4
GOBIN 5
GOROOT 5
Running Go online 6
The Go Playground 6
In action 6
Chapter 2: Arrays 8
Introduction 8
Syntax 8
Examples 8
Creating arrays 8
Multidimensional Array 9
Array Indexes 10
Syntax 12
Remarks 12
Examples 12
Encoding 12
Encoding to a String 12
Decoding 12
Decoding a String 13
Examples 14
controllers 14
core 15
libs 15
middlewares 15
public 16
h21 16
routers 16
services 18
main.go 18
Chapter 5: Branching 20
Examples 20
Switch Statements 20
If Statements 21
Goto statements 23
Break-continue statements 23
Syntax 25
Remarks 25
Examples 25
Chapter 7: cgo 27
Examples 27
www.dbooks.org
What 27
How 27
The example 27
Hello World! 28
Sum of ints 29
Generating a binary 30
Chapter 8: cgo 32
Examples 32
Chapter 9: Channels 36
Introduction 36
Syntax 36
Remarks 36
Examples 36
Using range 36
Timeouts 37
Coordinating goroutines 37
Buffered vs unbuffered 38
Examples 41
Closure Basics 41
Introduction 43
Syntax 43
Remarks 43
Examples 43
Creating goroutines 43
Stopping goroutines 45
Examples 48
Remarks 50
Examples 50
Declaring a constant 50
Syntax 53
Remarks 53
Further Reading 53
Examples 53
Introduction 56
Syntax 56
Remarks 56
Examples 57
Installation 59
Usage 59
www.dbooks.org
Introduction 60
Examples 60
Foreword 60
Encryption 60
Step 1 61
Step 2 61
Step 3 61
Step 4 61
Step 5 62
Step 6 62
Step 7 62
Step 8 62
Step 9 62
Step 10 63
Decryption 63
Step 1 63
Step 2 63
Step 3 63
Step 4 63
Step 5 64
Step 6 64
Step 7 64
Step 8 64
Step 9 64
Step 10 64
Introduction 66
Syntax 66
Remarks 66
Examples 66
Defer Basics 66
Introduction 70
Syntax 70
Remarks 70
Examples 71
Build tags 71
File suffix 71
Introduction 73
Remarks 73
Examples 73
Returning an error 75
Handling an error 76
Examples 79
Syntax 81
Parameters 81
Examples 82
www.dbooks.org
Listing all the files and folders in the current directory 82
Examples 84
Stringer 84
Basic fmt 84
Format Functions 84
Print 85
Sprint 85
Fprint 85
Scan 85
Stringer Interface 85
Introduction 86
Syntax 86
Examples 86
Basic Declaration 86
Parameters 86
Return Values 86
Variadic functions 89
Introduction 90
Examples 90
Create $GO_PATH/gulpfile.js 92
Create $GO_PATH/mypackage/source.go 93
Creating $GO_PATH/main.go 93
Introduction 97
Examples 97
How to encode data and write to file with gob? 97
Introduction 101
Examples 101
Syntax 103
Parameters 103
Remarks 103
Examples 103
1.7+ 105
Remarks 108
Examples 108
Handling http method, accessing query strings & request body 114
www.dbooks.org
Chapter 29: Images 116
Introduction 116
Examples 116
Remarks 124
Examples 124
Examples 127
Remarks 128
Downloading Go 128
Linux 128
Windows 129
Mac 129
Linux 129
Finished! 130
Examples 130
Example .profile or .bash_profile 130
Remarks 131
Examples 131
Introduction 137
Remarks 137
Examples 137
Syntax 140
Remarks 140
Examples 140
www.dbooks.org
Encoding/Decoding using Go structs 146
Encoding 146
Decoding 147
Introduction 148
Remarks 148
Examples 148
Parsing and validating a token using the HMAC signing method 148
Creating, signing, and encoding a JWT token using the HMAC signing method 149
Examples 152
Introduction 154
Examples 154
Introduction 160
Syntax 160
Remarks 160
Examples 160
Introduction 169
Examples 169
sync.Pool 169
Syntax 171
Examples 171
Introduction 174
Remarks 174
Examples 174
Example 174
Introduction 176
Remarks 176
Examples 176
www.dbooks.org
Middleware Calculate time required for handlerFunc to execute 176
Examples 178
Remarks 179
Examples 179
Structs 179
Methods 180
Syntax 184
Parameters 184
Examples 184
Examples 186
Remarks 190
Examples 190
Panic 190
Recover 190
Chapter 49: Parsing Command Line Arguments And Flags 192
Examples 192
Flags 192
Syntax 194
Examples 194
Introduction 195
Examples 195
Syntax 196
Examples 196
Remarks 201
Examples 201
www.dbooks.org
Introduction 204
Remarks 204
Examples 204
Examples 206
Remarks 207
Examples 207
Structs 207
Slices 208
reflect.Value.Elem() 208
Introduction 210
Syntax 210
Examples 210
Syntax 213
Examples 213
Introduction 215
Syntax 215
Examples 215
Remarks 221
Examples 221
Querying 221
MySQL 221
MongoDB: connect & insert & remove & update & query 222
Introduction 225
Syntax 225
Examples 225
Introduction 229
Examples 229
Embedding 230
Methods 231
Tags 233
www.dbooks.org
Chapter 63: Templates 237
Syntax 237
Remarks 237
Examples 237
Output values of struct variable to Standard Output using a text template 237
Introduction 239
Examples 239
Examples 247
Introduction 254
Examples 254
Go Run 254
Go Build 254
Go Clean 255
Go Fmt 255
Go Get 256
Go env 257
Introduction 258
Syntax 258
Examples 258
Examples 261
Syntax 263
Examples 263
Remarks 266
Examples 266
Usage 268
www.dbooks.org
vendor.json using Govendor tool 268
Examples 270
Remarks 274
Examples 274
Examples 276
Remarks 277
Examples 277
Examples 279
Explanation 279
Credits 281
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: go
It is an unofficial and free Go ebook created for educational purposes. All the content is extracted
from Stack Overflow Documentation, which is written by many hardworking individuals at Stack
Overflow. It is neither affiliated with Stack Overflow nor official Go.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
www.dbooks.org
Chapter 1: Getting started with Go
Remarks
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.
Versions
The latest major version release is in bold below. Full release history can be
found here.
1.8.3 2017-05-24
1.8.0 2017-02-16
1.7.0 2016-08-15
1.6.0 2016-02-17
1.5.0 2015-08-19
1.4.0 2014-12-04
1.3.0 2014-06-18
1.2.0 2013-12-01
1.1.0 2013-05-13
1.0.0 2012-03-28
Examples
Hello, World!
package main
import "fmt"
func main() {
https://riptutorial.com/ 2
fmt.Println("Hello, ")
}
Playground
When Go is installed correctly this program can be compiled and run like this:
go run hello.go
Output:
Hello,
Once you are happy with the code it can be compiled to an executable by running:
go build hello.go
This will create an executable file appropriate for your operating system in the current directory,
which you can then run with the following command:
./hello
Windows
hello.exe
Note: The Chinese characters are important because they demonstrate that Go strings are stored
as read-only slices of bytes.
FizzBuzz
Another example of "Hello World" style programs is FizzBuzz. This is one example of a FizzBuzz
implementation. Very idiomatic Go in play here.
package main
import "fmt"
func main() {
for i := 1; i <= 100; i++ {
s := ""
if i % 3 == 0 {
s += "Fizz"
}
https://riptutorial.com/ 3
www.dbooks.org
if i % 5 == 0 {
s += "Buzz"
}
if s != "" {
fmt.Println(s)
} else {
fmt.Println(i)
}
}
}
Playground
Environment variables that affect the go tool can be viewed via the go env [var ...] command:
$ go env
GOARCH="amd64"
GOBIN="/home/yourname/bin"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/yourname"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-
build059426571=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
By default it prints the list as a shell script; however, if one or more variable names are given as
arguments, it prints the value of each named variable.
If Go is not pre-installed in your system you can go to https://golang.org/dl/ and choose your
platform to download and install Go.
To set up a basic Go development environment, only a few of the many environment variables that
affect the behavior of the go tool (See: Listing Go Environment Variables for a full list) need to be
set (generally in your shell's ~/.profile file, or equivalent on Unix-like OSs).
GOPATH
Like the system PATH environment variable, Go path is a :(; on Windows) delimited list of
https://riptutorial.com/ 4
directories where Go will look for packages. The go get tool will also download packages to the
first directory in this list.
The GOPATH is where Go will setup associated bin, pkg, and src folders needed for the workspace:
From Go 1.8 onwards, the GOPATH environment variable will have a default value if it is unset. It
defaults to $HOME/go on Unix/Linux and %USERPROFILE%/go on Windows.
GOBIN
The bin directory where go install and go get will place binaries after building main packages.
Generally this is set to somewhere on the system PATH so that installed binaries can be run and
discovered easily.
GOROOT
This is the location of your Go installation. It is used to find the standard libraries. It is very rare to
have to set this variable as Go embeds the build path into the toolchain. Setting GOROOT is needed if
the installation directory differs from the build directory (or the value set when building).
godoc -http=:<port-number>
go tool tour
The two commands above will start web-servers with documentation similar to what is found
online here and here respectively.
go help [command]
https://riptutorial.com/ 5
www.dbooks.org
Running Go online
The Go Playground
One little known Go tool is The Go Playground. If one wants to experiment with Go without
downloading it, they can easily do so simply by . . .
In action
https://riptutorial.com/ 6
https://riptutorial.com/ 7
www.dbooks.org
Chapter 2: Arrays
Introduction
Arrays are specific data type, representing an ordered collection of elements of another type.
In Go, Arrays can be simple (sometime called "lists") or multi-dimensional (like for example a 2-
dimentions arrays is representing a ordered collection of arrays, that contains elements)
Syntax
• var variableName [5]ArrayType // Declaring an array of size 5.
• var variableName [2][3]ArrayType = { {Value1, Value2, Value3}, {Value4, Value5, Value6} } //
Declaring a multidimensional array
• variableName := [...]ArrayType {Value1, Value2, Value3} // Declare an array of size 3 (The
compiler will count the array elements to define the size)
• arrayName[2] // Getting the value by index.
• arrayName[5] = 0 // Setting the value at index.
• arrayName[0] // First value of the Array
• arrayName[ len(arrayName)-1 ] // Last value of the Array
Examples
Creating arrays
Creating a new array looks like var array = [size]Type, replacing size by a number (for example 42
to specify it will be a list of 42 elements), and replacing Type by the type of the elements the array
can contains (for example int or string)
Just below it's a code example showing the different way to create an array in Go.
https://riptutorial.com/ 8
ptrs := [8]*int{} // a list of int pointers, filled with 8 nil references (
<nil> )
emptystr := [8]string{} // a list of string filled with 8 times ""
play it on playground
Multidimensional Array
For example, [2][3]int is representing an array composed of 2 sub arrays of 3 int typed
elements.
It can basically be the representation of a matrix of 2 lines and 3 columns.
So we can make huge dimensions number array like var values := [2017][12][31][24][60]int for
example if you need to store a number for each minutes since Year 0.
To access this kind of array, for the last example, searching for the value of 2016-01-31 at 19:42,
you will access values[2016][0][30][19][42] (because array indexes starts at 0 and not at 1 like
days and months)
https://riptutorial.com/ 9
www.dbooks.org
fmt.Println(multiDimArray)
// > [[1 2 3] [4 5 6]]
fmt.Println(multiDimArray[0])
// > [1 2 3] (first line of the array)
fmt.Println(multiDimArray[0][1])
// > 2 (cell of line 0 (the first one), column 1 (the 2nd one))
fmt.Println(multiDimArray);
// Yeah, many dimensions stores many data
// > [[[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]]
// [[[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]]
fmt.Println(multiDimArray);
// If we could see in 4 dimensions, maybe we could see the result as a simple format
// > [[[["All zero indexes" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]]
// [[[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" ""]]]
// [[["" ""] ["" ""]] [["" ""] ["" ""]] [["" ""] ["" "All indexes to max"]]]]
Array Indexes
Arrays values should be accessed using a number specifying the location of the desired value in
the array. This number is called Index.
To access a value, you have to do something like this: arrayName[index], replacing "index" by the
number corresponding to the rank of the value in your array.
For example:
https://riptutorial.com/ 10
fmt.Println(array[0]) // > 1
fmt.Println(array[1]) // > 2
fmt.Println(array[2]) // > 3
fmt.Println(array[3]) // > 4
fmt.Println(array[4]) // > 5
fmt.Println(array[5]) // > 6
fmt.Println(array[6]) // invalid array index 6 (out of bounds for 6-element array)
fmt.Println(array[42]) // invalid array index 42 (out of bounds for 6-element array)
fmt.Println(array) // > [1 2 3 4 5 6]
array[0] := 6
fmt.Println(array) // > [6 2 3 4 5 6]
array[1] := 5
fmt.Println(array) // > [6 5 3 4 5 6]
array[2] := 4
fmt.Println(array) // > [6 5 4 4 5 6]
array[3] := 3
fmt.Println(array) // > [6 5 4 3 5 6]
array[4] := 2
fmt.Println(array) // > [6 5 4 3 2 6]
array[5] := 1
fmt.Println(array) // > [6 5 4 3 2 1]
https://riptutorial.com/ 11
www.dbooks.org
Chapter 3: Base64 Encoding
Syntax
• func (enc *base64.Encoding) Encode(dst, src []byte)
• func (enc *base64.Encoding) Decode(dst, src []byte) (n int, err error)
• func (enc *base64.Encoding) EncodeToString(src []byte) string
• func (enc *base64.Encoding) DecodeString(s string) ([]byte, error)
Remarks
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.
Examples
Encoding
Playground
Encoding to a String
Playground
Decoding
encoding := base64.StdEncoding
data := []byte(`Zm9vIGJhcg==`)
decoded := make([]byte, encoding.DecodedLen(len(data)))
n, err := encoding.Decode(decoded, data)
if err != nil {
log.Fatal(err)
}
https://riptutorial.com/ 12
// (only the max length), we need to trim the buffer to whatever
// the actual length of the decoded data was.
decoded = decoded[:n]
fmt.Printf("`%s`", decoded)
// Output: `foo bar`
Playground
Decoding a String
fmt.Printf("%s", decoded)
// Output: n,,
Playground
https://riptutorial.com/ 13
www.dbooks.org
Chapter 4: Best practices on project structure
Examples
Restfull Projects API with Gin
Gin is a web framework written in Golang. It features a martini-like API with much
better performance, up to 40 times faster. If you need performance and good
productivity, you will love Gin.
1. controllers
2. core
3. libs
4. middlewares
5. public
6. routers
7. services
8. tests
9. main.go
controllers
Controllers package will store all the API logic. Whatever your API, your logic will happen here
https://riptutorial.com/ 14
core
Core package will store all your created models, ORM, etc
libs
This package will store any library that used in projects. But only for manually created/imported
library, that not available when using go get package_name commands. Could be your own hashing
algorithm, graph, tree etc.
middlewares
This package store every middleware that used in project, could be creation/validation of
cors,device-id , auth etc
https://riptutorial.com/ 15
www.dbooks.org
public
This pacakge will store every public and static files, could be html, css, javascript ,images, etc
routers
This package will store every routes in your REST API.
https://riptutorial.com/ 16
auth_r.go
import (
auth "simple-api/controllers/v1/auth"
"gopkg.in/gin-gonic/gin.v1"
)
/**
* @api {post} /v1/auth/login Login
* @apiGroup Users
* @apiHeader {application/json} Content-Type Accept application/json
* @apiParam {String} username User username
* @apiParam {String} password User Password
* @apiParamExample {json} Input
* {
* "username": "your username",
* "password" : "your password"
* }
* @apiSuccess {Object} authenticate Response
* @apiSuccess {Boolean} authenticate.success Status
* @apiSuccess {Integer} authenticate.statuscode Status Code
* @apiSuccess {String} authenticate.message Authenticate Message
* @apiSuccess {String} authenticate.token Your JSON Token
* @apiSuccessExample {json} Success
* {
* "authenticate": {
* "statuscode": 200,
* "success": true,
* "message": "Login Successfully",
* "token":
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRyd
* }
* }
* @apiErrorExample {json} List error
* HTTP/1.1 500 Internal Server Error
*/
router.POST("/auth/login" , auth.Login)
}
If you see, the reason I separate the handler is, to easy us to manage each routers. So I can
create comments about the API , that with apidoc will generate this into structured documentation.
Then I will call the function in index.go in current package
index.go
package v1
import (
"gopkg.in/gin-gonic/gin.v1"
token "simple-api/middlewares/token"
appid "simple-api/middlewares/appid"
)
func InitRoutes(g *gin.RouterGroup) {
https://riptutorial.com/ 17
www.dbooks.org
g.Use(appid.AppIDMiddleWare())
SetHelloRoutes(g)
SetAuthRoutes(g) // SetAuthRoutes invoked
g.Use(token.TokenAuthMiddleWare()) //secure the API From this line to bottom with JSON
Auth
g.Use(appid.ValidateAppIDMiddleWare())
SetTaskRoutes(g)
SetUserRoutes(g)
}
services
This package will store any configuration and setting to used in project from any used service,
could be mongodb,redis,mysql, elasticsearch, etc.
main.go
The main entrance of the API. Any configuration about the dev environment settings,
systems,port, etc will configured here.
Example:
main.go
package main
import (
"fmt"
"net/http"
"gopkg.in/gin-gonic/gin.v1"
"articles/services/mysql"
"articles/routers/v1"
"articles/core/models"
)
func init() {
mysql.CheckDB()
router = gin.New();
router.NoRoute(noRouteHandler())
version1:=router.Group("/v1")
https://riptutorial.com/ 18
v1.InitRoutes(version1)
func main() {
fmt.Println("Server Running on Port: ", 9090)
http.ListenAndServe(":9090",router)
}
https://riptutorial.com/ 19
www.dbooks.org
Chapter 5: Branching
Examples
Switch Statements
switch a + b {
case c:
// do something
case d:
// do something else
default:
// do something entirely different
}
if a + b == c {
// do something
} else if a + b == d {
// do something else
} else {
// do something entirely different
}
The default clause is optional and will be executed if and only if none of the cases compare true,
even if it does not appear last, which is acceptable. The following is semantically the same as the
first example:
switch a + b {
default:
// do something entirely different
case c:
// do something
case d:
// do something else
}
This could be useful if you intend to use the fallthrough statement in the default clause, which
must be the last statement in a case and causes program execution to proceed to the next case:
switch a + b {
default:
// do something entirely different, but then also do something
fallthrough
case c:
// do something
case d:
https://riptutorial.com/ 20
// do something else
}
switch {
case a + b == c:
// do something
case a + b == d:
// do something else
}
switch n := getNumber(); n {
case 1:
// do something
case 2:
// do something else
}
Cases can be combined in a comma-separated list if they share the same logic:
switch a + b {
case c, d:
// do something
default:
// do something entirely different
}
If Statements
A simple if statement:
if a == b {
// do something
}
Note that there are no parentheses surrounding the condition and that the opening curly brace {
must be on the same line. The following will not compile:
if a == b
{
// do something
}
if a == b {
https://riptutorial.com/ 21
www.dbooks.org
// do something
} else if a == c {
// do something else
} else {
// do something entirely different
}
Per golang.org's documentation, "The expression may be preceded by a simple statement, which
executes before the expression is evaluated." Variables declared in this simple statement are
scoped to the if statement and cannot be accessed outside it:
You can test for any type, including error, user-defined types, interface types, and function types:
switch t := x.(type) {
case error:
log.Fatal(t)
case myType:
fmt.Println(myType.message)
case myInterface:
t.MyInterfaceMethod()
case func(string) bool:
if t("Hello world?") {
fmt.Println("Hello world!")
}
https://riptutorial.com/ 22
}
Goto statements
A goto statement transfers control to the statement with the corresponding label within the same
function. Executing the goto statement must not cause any variables to come into scope that were
not already in scope at the point of the goto.
for x < 0 {
if x > -1e-09 {
goto small
}
z = z / x
x = x + 1
}
for x < 2 {
if x < 1e-09 {
goto small
}
z = z / x
x = x + 1
}
if x == 2 {
return z
}
x = x - 2
p = (((((x*_gamP[0]+_gamP[1])*x+_gamP[2])*x+_gamP[3])*x+_gamP[4])*x+_gamP[5])*x + _gamP[6]
q =
((((((x*_gamQ[0]+_gamQ[1])*x+_gamQ[2])*x+_gamQ[3])*x+_gamQ[4])*x+_gamQ[5])*x+_gamQ[6])*x +
_gamQ[7]
return z * p / q
small:
if x == 0 {
return Inf(1)
}
return z / ((1 + Euler*x) * x)
Break-continue statements
The break statement, on execution makes the current loop to force exit
package main
import "fmt"
func main() {
i:=0
for true {
if i>2 {
break
https://riptutorial.com/ 23
www.dbooks.org
}
fmt.Println("Iteration : ",i)
i++
}
}
The continue statement, on execution moves the control to the start of the loop
import "fmt"
func main() {
j:=100
for j<110 {
j++
if j%2==0 {
continue
}
fmt.Println("Var : ",j)
}
}
import "fmt"
func main() {
j := 100
loop:
for j < 110 {
j++
switch j % 3 {
case 0:
continue loop
case 1:
break loop
}
fmt.Println("Var : ", j)
}
}
https://riptutorial.com/ 24
Chapter 6: Build Constraints
Syntax
• // +build tags
Remarks
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.
Examples
Separate integration tests
Build constraints are commonly used to separate normal unit tests from integration tests that
require external resources, like a database or network access. To do this, add a custom build
constraint to the top of the test file:
// +build integration
package main
import (
"testing"
)
The test file will not compile into the build executable unless the following invocation of go test is
used:
Results:
$ go test
? bitbucket.org/yourname/yourproject [no test files]
https://riptutorial.com/ 25
www.dbooks.org
$ go test -tags "integration"
--- FAIL: TestThatRequiresNetworkAccess (0.00s)
main_test.go:10: It failed!
FAIL
exit status 1
FAIL bitbucket.org/yourname/yourproject 0.003s
We can optimize a simple xor function for only architectures that support unaligned reads/writes by
creating two files that define the function and prefixing them with a build constraint (for an actual
example of the xor code which is out of scope here, see crypto/cipher/xor.go in the standard
library):
package cipher
func xorBytes(dst, a, b []byte) int { /* This function uses unaligned reads / writes to
optimize the operation */ }
// +build !386,!amd64,!s390x
package cipher
func xorBytes(dst, a, b []byte) int { /* This version of the function just loops and xors */ }
https://riptutorial.com/ 26
Chapter 7: cgo
Examples
Cgo: First steps tutorial
What
In Go you can call C programs and functions using cgo. This way you can easily create C bindings
to other applications or libraries that provides C API.
How
All you need to do is to add a import "C" at the beginning of your Go program just after including
your C program:
//#include <stdio.h>
import "C"
With the previous example you can use the stdio package in Go.
If you need to use an app that is on your same folder, you use the same syntax than in C (with the
" instead of <>)
//#include "hello.c"
import "C"
IMPORTANT: Do not leave a newline between the include and the import "C"
statements or you will get this type of errors on build:
# command-line-arguments
could not determine kind of name for C.Hello
could not determine kind of name for C.sum
The example
On this folder you can find an example of C bindings. We have two very simple C "libraries" called
hello.c:
//hello.c
#include <stdio.h>
void Hello(){
https://riptutorial.com/ 27
www.dbooks.org
printf("Hello world\n");
}
//sum.c
#include <stdio.h>
...that takes 2 arguments and returns its sum (do not print it).
We have a main.go program that will make use of this two files. First we import them as we
mentioned before:
//main.go
package main
/*
#include "hello.c"
#include "sum.c"
*/
import "C"
Hello World!
Now we are ready to use the C programs in our Go app. Let's first try the Hello program:
//main.go
package main
/*
#include "hello.c"
#include "sum.c"
*/
import "C"
func main() {
//Call to void function without params
err := Hello()
if err != nil {
log.Fatal(err)
}
}
//Hello is a C binding to the Hello World "C" program. As a Go user you could
//use now the Hello function transparently without knowing that it is calling
//a C function
func Hello() error {
_, err := C.Hello() //We ignore first result as it is a void function
if err != nil {
return errors.New("error calling Hello function: " + err.Error())
}
https://riptutorial.com/ 28
return nil
}
Now run the main.go program using the go run main.go to get print of the C program: "Hello
world!". Well done!
Sum of ints
Let's make it a bit more complex by adding a function that sums its two arguments.
//sum.c
#include <stdio.h>
//main.go
package main
/*
#include "hello.c"
#include "sum.c"
*/
import "C"
import (
"errors"
"fmt"
"log"
)
func main() {
//Call to void function without params
err := Hello()
if err != nil {
log.Fatal(err)
}
//Hello is a C binding to the Hello World "C" program. As a Go user you could
//use now the Hello function transparently without knowing that is calling a C
//function
func Hello() error {
_, err := C.Hello() //We ignore first result as it is a void function
if err != nil {
https://riptutorial.com/ 29
www.dbooks.org
return errors.New("error calling Hello function: " + err.Error())
}
return nil
}
Take a look at the "makeSum" function. It receives two int parameters that need to be converted
to C int before by using the C.int function. Also, the return of the call will give us a C int and an
error in case something went wrong. We need to cast C response to a Go's int using int().
$ go run main.go
Hello world!
Sum of 5 + 4 is 9
Generating a binary
If you try a go build you could get multiple definition errors.
$ go build
# github.com/sayden/c-bindings
/tmp/go-build329491076/github.com/sayden/c-bindings/_obj/hello.o: In function `Hello':
../../go/src/github.com/sayden/c-bindings/hello.c:5: multiple definition of `Hello'
/tmp/go-build329491076/github.com/sayden/c-
bindings/_obj/main.cgo2.o:/home/mariocaster/go/src/github.com/sayden/c-bindings/hello.c:5:
first defined here
/tmp/go-build329491076/github.com/sayden/c-bindings/_obj/sum.o: In function `sum':
../../go/src/github.com/sayden/c-bindings/sum.c:5: multiple definition of `sum`
/tmp/go-build329491076/github.com/sayden/c-
bindings/_obj/main.cgo2.o:/home/mariocaster/go/src/github.com/sayden/c-bindings/sum.c:5: first
defined here
collect2: error: ld returned 1 exit status
The trick is to refer to the main file directly when using go build:
https://riptutorial.com/ 30
$ go build main.go
$ ./main
Hello world!
Sum of 5 + 4 is 9
Remember that you can provide a name to the binary file by using -o flag go build -o
my_c_binding main.go
https://riptutorial.com/ 31
www.dbooks.org
Chapter 8: cgo
Examples
Calling C Function From Go
import "C"
import "fmt"
And it is good style to use the factored import statement, for other imports, like:
import "C"
import (
"fmt"
"math"
)
package main
func main() {
a := C.int(10)
b := C.int(20)
c := C.Add(a, b)
fmt.Println(c) // 30
}
30
To build cgo packages, just use go build or go install as usual. The go tool recognizes the special
"C" import and automatically uses cgo for those files.
https://riptutorial.com/ 32
Wire C and Go code in all directions
package main
/*
// Everything in comments above the import "C" is C code and will be compiles with the GCC.
// Make sure you have a GCC installed.
func main() {
a := 3
b := 5
c := C.addInC(C.int(a), C.int(b))
package main
/*
static inline int multiplyInGo(int a, int b) {
return go_multiply(a, b);
}
*/
import "C"
import (
"fmt"
)
func main() {
a := 3
b := 5
c := C.multiplyInGo(C.int(a), C.int(b))
//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
package main
https://riptutorial.com/ 33
www.dbooks.org
/*
int go_multiply(int a, int b);
func main() {
a := 3
b := 5
C.init(); // OR:
C.multiply = C.multiply_f(go_multiply);
c := C.multiplyWithFp(C.int(a), C.int(b))
//export go_multiply
func go_multiply(a C.int, b C.int) C.int {
return a * b
}
// Go string to C string
// The C string is allocated in the C heap using malloc.
// It is the caller's responsibility to arrange for it to be
// freed, such as by calling C.free (be sure to include stdlib.h
// if C.free is needed).
func C.CString(string) *C.char
// C string to Go string
func C.GoString(*C.char) string
https://riptutorial.com/ 34
// C data with explicit length to Go []byte
func C.GoBytes(unsafe.Pointer, C.int) []byte
// ...
// ...
https://riptutorial.com/ 35
www.dbooks.org
Chapter 9: Channels
Introduction
A channel contains values of a given type. Values can be written to a channel and read from it,
and they circulate inside the channel in first-in-first-out order. There is a distinction between
buffered channels, which can contain several messages, and unbuffered channels, which cannot.
Channels are typically used to communicate between goroutines, but are also useful in other
circumstances.
Syntax
• make(chan int) // create an unbuffered channel
• make(chan int, 5) // create a buffered channel with a capacity of 5
• close(ch) // closes a channel "ch"
• ch <- 1 // write the value of 1 to a channel "ch"
• val := <-ch // read a value from channel "ch"
• val, ok := <-ch // alternate syntax; ok is a bool indicating if the channel is closed
Remarks
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.
Examples
Using range
When reading multiple values from a channel, using range is a common pattern:
go func() {
ch <- 1
ch <- 2
ch <- 3
close(ch)
}()
return ch
}
https://riptutorial.com/ 36
func main() {
for n := range foo() {
fmt.Println(n)
}
Playground
Output
1
2
3
channel is now closed
Timeouts
func main() {
// Create a buffered channel to prevent a goroutine leak. The buffer
// ensures that the goroutine below can eventually terminate, even if
// the timeout is met. Without the buffer, the send on the channel
// blocks forever, waiting for a read that will never happen, and the
// goroutine is leaked.
ch := make(chan struct{}, 1)
go func() {
time.Sleep(10 * time.Second)
ch <- struct{}{}
}()
select {
case <-ch:
// Work completed before timeout.
case <-time.After(1 * time.Second):
// Work was not completed after 1 second.
}
}
Coordinating goroutines
Imagine a goroutine with a two step process, where the main thread needs to do some work
between each step:
func main() {
ch := make(chan struct{})
go func() {
// Wait for main thread's signal to begin step one
<-ch
// Perform work
time.Sleep(1 * time.Second)
https://riptutorial.com/ 37
www.dbooks.org
// Signal to main thread that step one has completed
ch <- struct{}{}
// Perform work
time.Sleep(1 * time.Second)
// Wait for notification from goroutine that step one has completed
<-ch
// Wait for notification from goroutine that step two has completed
<-ch
}
Buffered vs unbuffered
https://riptutorial.com/ 38
fmt.Println(">", i, "sent!")
time.Sleep(25 * time.Millisecond)
}
// We'll close the channel, so that the range over channel
// below can terminate.
close(ch)
}()
for i := range ch {
// For each task sent on the channel, we would perform some
// task. In this case, we will assume the job is to
// "sleep 100ms".
fmt.Println("<", i, "received, performing 100ms job")
time.Sleep(100 * time.Millisecond)
fmt.Println("<", i, "job done")
}
}
go playground
By default communication over the channcels is sync; when you send some value there must be a
receiver. Otherwise you will get fatal error: all goroutines are asleep - deadlock! as follows:
package main
import "fmt"
func main() {
msg := make(chan string)
msg <- "Hey There"
go func() {
fmt.Println(<-msg)
}()
}
package main
import "fmt"
import "time"
func main() {
msg :=make(chan string, 1)
msg <- "Hey There!"
go func() {
fmt.Println(<-msg)
}()
time.Sleep(time.Second * 1)
}
A common technique for using channels is to create some number of workers (or consumers) to
https://riptutorial.com/ 39
www.dbooks.org
read from the channel. Using a sync.WaitGroup is an easy way to wait for those workers to finish
running.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
numPiecesOfWork := 20
numWorkers := 5
// Start workers
wg.Add(numWorkers)
for i := 0; i < numWorkers; i++ {
go worker(workCh, wg)
}
// Send work
for i := 0; i < numPiecesOfWork; i++ {
work := i % 10 // invent some work
workCh <- work
}
fmt.Println("done")
}
for work := range workCh { // will wait for work until workCh is closed
doWork(work)
}
}
https://riptutorial.com/ 40
Chapter 10: Closures
Examples
Closure Basics
func g() {
i := 0
f := func() { // anonymous function
fmt.Println("f called")
}
}
Within the body of an anonymous function (say f) defined within another function (say g), variables
present in scopes of both f and g are accessible. However, it is the scope of g that forms the
environment part of the closure (function part is f) and as a result, changes made to the variables
in g's scope retain their values (i.e. the environment persists between calls to f).
In above definition, NaturalNumbers has an inner function f which NaturalNumbers returns. Inside f,
variable i defined within the scope of NaturalNumbers is being accessed.
n := NaturalNumbers()
Now n is a closure. It is a function (defined by f) which also has an associated environment (scope
of NaturalNumbers).
https://riptutorial.com/ 41
www.dbooks.org
fmt.Println(n()) // 1
fmt.Println(n()) // 2
fmt.Println(n()) // 3
As evident from above output, each time n is called, it increments i. i starts at 0, and each call to n
executes i++.
The value of i is retained between calls. That is, the environment, being a part of closure, persists.
Calling NaturalNumbers again would create and return a new function. This would initialize a new i
within NaturalNumbers. Which means that the newly returned function forms another closure having
the same part for function (still f) but a brand new environment (a newly initialized i).
o := NaturalNumbers()
fmt.Println(n()) // 4
fmt.Println(o()) // 1
fmt.Println(o()) // 2
fmt.Println(n()) // 5
Both n and o are closures containing same function part (which gives them the same behavior),
but different environments. Thus, use of closures allow functions to have access to a persistent
environment that can be used to retain information between calls.
Another example:
two := multiples(2)
fmt.Println(two(), two(), two()) // 2 4 6
fortyTwo := multiples(42)
fmt.Println(fortyTwo(), fortyTwo(), fortyTwo()) // 42 84 126
https://riptutorial.com/ 42
Chapter 11: Concurrency
Introduction
In Go, concurrency is achieved through the use of goroutines, and communication between
goroutines is usually done with channels. However, other means of synchronization, like mutexes
and wait groups, are available, and should be used whenever they are more convenient than
channels.
Syntax
• go doWork() // run the function doWork as a goroutine
• ch := make(chan int) // declare new channel of type int
• ch <- 1 // sending on a channel
• value = <-ch // receiving from a channel
Remarks
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.
Examples
Creating goroutines
Any function can be invoked as a goroutine by prefixing its invocation with the keyword go:
https://riptutorial.com/ 43
www.dbooks.org
single channel, single goroutine, one write, one read.
package main
import "fmt"
import "time"
func main() {
// create new channel of type string
ch := make(chan string)
Run it on playground
The time.Sleep is here to illustrate main() function will wait on the ch channel, which means the
function literal executed as a goroutine has the time to send a value through that channel: the
receive operator <-ch will block the execution of main(). If it didn't, the goroutine would be killed
when main() exits, and would not have time to send its value.
Go programs end when the main function ends, therefore it is common practice to wait for all
goroutines to finish. A common solution for this is to use a sync.WaitGroup object.
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup // 1
func main() {
wg.Add(10) // 2
for i := 0; i < 10; i++ {
go routine(i) // *
}
wg.Wait() // 4
https://riptutorial.com/ 44
fmt.Println("main finished")
}
1. Declaration of global variable. Making it global is the easiest way to make it visible to all
functions and methods.
2. Increasing the counter. This must be done in the main goroutine because there is no
guarantee that a newly started goroutine will execute before 4 due to memory model
guarantees.
3. Decreasing the counter. This must be done at the exit of a goroutine. By using a deferred
call, we make sure that it will be called whenever function ends, no matter how it ends.
4. Waiting for the counter to reach 0. This must be done in the main goroutine to prevent the
program from exiting before all goroutines have finished.
* Parameters are evaluated before starting a new goroutine. Thus it is necessary to define their
values explicitly before wg.Add(10) so that possibly-panicking code will not increase the counter.
Adding 10 items to the WaitGroup, so it will wait for 10 items before wg.Wait returns the control
back to main() goroutine. Here, the value of i is defined in the for loop.
When in a loop, the loop variable (val) in the following example is a single variable that changes
value as it goes over the loop. Therefore one must do the following to actually pass each val of
values to the goroutine:
If you were to do just do go func(val interface{}) { ... }() without passing val, then the value of
val will be whatever val is when the goroutines actually runs.
The strange-looking val := val creates a new variable in each iteration, which is then accessed by
the goroutine.
Stopping goroutines
https://riptutorial.com/ 45
www.dbooks.org
package main
import (
"log"
"sync"
"time"
)
func main() {
// The WaitGroup lets the main goroutine wait for all other goroutines
// to terminate. However, this is no implicit in Go. The WaitGroup must
// be explicitely incremented prior to the execution of any goroutine
// (i.e. before the `go` keyword) and it must be decremented by calling
// wg.Done() at the end of every goroutine (typically via the `defer` keyword).
wg := sync.WaitGroup{}
// The stop channel is an unbuffered channel that is closed when the main
// thread wants all other goroutines to terminate (there is no way to
// interrupt another goroutine in Go). Each goroutine must multiplex its
// work with the stop channel to guarantee liveness.
stopCh := make(chan struct{})
select {
// Since we never send empty structs on this channel we can
// take the return of a receive on the channel to mean that the
// channel has been closed (recall that receive never blocks on
// closed channels).
case <-stopCh:
log.Printf("stopped goroutine %d", i)
}
}(i, stopCh)
}
time.Sleep(time.Second * 5)
close(stopCh)
log.Printf("stopping goroutines")
wg.Wait()
log.Printf("all goroutines stopped")
}
package main
import (
https://riptutorial.com/ 46
"fmt"
"time"
)
func main() {
ping := make(chan int)
pong := make(chan int)
go pinger(ping, pong)
go ponger(ping, pong)
// The main goroutine starts the ping/pong by sending into the ping channel
ping <- 1
for {
// Block the main thread until an interrupt
time.Sleep(time.Second)
}
}
https://riptutorial.com/ 47
www.dbooks.org
Chapter 12: Console I/O
Examples
Read input from console
Using scanf
Scanf scans text read from standard input, storing successive space-separated values
into successive arguments as determined by the format. It returns the number of items
successfully scanned. If that is less than the number of arguments, err will report why.
Newlines in the input must match newlines in the format. The one exception: the verb
%c always scans the next rune in the input, even if it is a space (or tab etc.) or newline.
# Read integer
var i int
fmt.Scanf("%d", &i)
# Read string
var str string
fmt.Scanf("%s", &str)
Using scan
Scan scans text read from standard input, storing successive space-separated values
into successive arguments. Newlines count as space. It returns the number of items
successfully scanned. If that is less than the number of arguments, err will report why.
# Read integer
var i int
fmt.Scan(&i)
# Read string
var str string
fmt.Scan(&str)
Using scanln
Sscanln is similar to Sscan, but stops scanning at a newline and after the final item
there must be a newline or EOF.
# Read string
var input string
fmt.Scanln(&input)
Using bufio
https://riptutorial.com/ 48
text, err := reader.ReadString('\n')
https://riptutorial.com/ 49
www.dbooks.org
Chapter 13: Constants
Remarks
Go supports constants of character, string, boolean, and numeric values.
Examples
Declaring a constant
Constants are declared like variables, but using the const keyword:
Like for variables, names starting with an upper case letter are exported (public), names starting
with lower case are not.
// not exported
const alpha string = "Alpha"
// exported
const Beta string = "Beta"
Constants can be used like any other variable, except for the fact that the value cannot be
changed. Here's an example:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(s) // constant
https://riptutorial.com/ 50
}
Playground
You can declare multiple constants within the same const block:
const (
Alpha = "alpha"
Beta = "beta"
Gamma = "gamma"
)
const (
Zero = iota // Zero == 0
One // One == 1
Two // Two == 2
)
You can also declare multiple constants using the multiple assignment. However, this syntax may
be harder to read and it is generally avoided.
Constants in Go may be typed or untyped. For instance, given the following string literal:
"bar"
one might say that the type of the literal is string, however, this is not semantically correct.
Instead, literals are Untyped string constants. It is a string (more correctly, its default type is string
), but it is not a Go value and therefore has no type until it is assigned or used in a context that is
typed. This is a subtle distinction, but a useful one to understand.
It remains untyped since, by default, constants are untyped. It is possible to declare it as a typed
string constant as well:
https://riptutorial.com/ 51
www.dbooks.org
The difference comes into play when we attempt to assign these constants in a context that does
have type. For instance, consider the following:
var s string
s = foo // This works just fine
s = typedFoo // As does this
https://riptutorial.com/ 52
Chapter 14: Context
Syntax
• type CancelFunc func()
• func Background() Context
• func TODO() Context
• func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
• func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
• func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
• func WithValue(parent Context, key interface{}, val interface{})
Remarks
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
• https://blog.golang.org/context
Examples
Context tree represented as a directed graph
https://riptutorial.com/ 53
www.dbooks.org
A simple context tree (containing some common values that might be request scoped and
included in a context) built from Go code like the following:
// Pseudo-Go
ctx := context.WithValue(
context.WithDeadline(
context.WithValue(context.Background(), sidKey, sid),
time.Now().Add(30 * time.Minute),
),
ridKey, rid,
)
trCtx := trace.NewContext(ctx, tr)
logCtx := myRequestLogging.NewContext(ctx, myRequestLogging.NewLogger())
Is a tree that can be represented as a directed graph that looks like this:
Each child context has access to the values of its parent contexts, so the data access flows
upwards in the tree (represented by black edges). Cancelation signals on the other hand travel
down the tree (if a context is canceled, all of its children are also canceled). The cancelation signal
flow is represented by the grey edges.
Passing a context with a timeout (or with a cancel function) to a long running function can be used
to cancel that functions work:
https://riptutorial.com/ 54
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
// Do an iteration of some long running work here!
}
}
https://riptutorial.com/ 55
www.dbooks.org
Chapter 15: Cross Compilation
Introduction
The Go compiler can produce binaries for many platforms, i.e. processors and systems. Unlike
with most other compilers, there is no specific requirement to cross-compiling, it is as easy to use
as regular compiling.
Syntax
• GOOS=linux GOARCH=amd64 go build
Remarks
Supported Operating System and Architecture target combinations (source)
$GOOS $GOARCH
android arm
darwin 386
darwin amd64
darwin arm
darwin arm64
dragonfly amd64
freebsd 386
freebsd amd64
freebsd arm
linux 386
linux amd64
linux arm
linux arm64
linux ppc64
linux ppc64le
https://riptutorial.com/ 56
$GOOS $GOARCH
linux mips64
linux mips64le
netbsd 386
netbsd amd64
netbsd arm
openbsd 386
openbsd amd64
openbsd arm
plan9 386
plan9 amd64
solaris amd64
windows 386
windows amd64
Examples
Compile all architectures using a Makefile
This Makefile will cross compile and zip up executables for Windows, Mac and Linux (ARM and
x86).
clean:
rm -rf build/
https://riptutorial.com/ 57
www.dbooks.org
build/linux_amd64.tar.gz
build/linux_386.tar.gz: $(sources)
$(call build,linux,386,)
$(call tar,linux,386)
build/linux_amd64.tar.gz: $(sources)
$(call build,linux,amd64,)
$(call tar,linux,amd64)
build/linux_arm.tar.gz: $(sources)
$(call build,linux,arm,)
$(call tar,linux,arm)
build/linux_arm64.tar.gz: $(sources)
$(call build,linux,arm64,)
$(call tar,linux,arm64)
build/darwin_amd64.tar.gz: $(sources)
$(call build,darwin,amd64,)
$(call tar,darwin,amd64)
build/windows_386.zip: $(sources)
$(call build,windows,386,.exe)
$(call zip,windows,386,.exe)
build/windows_amd64.zip: $(sources)
$(call build,windows,amd64,.exe)
$(call zip,windows,amd64,.exe)
From your project directory, run the go build command and specify the operating system and
architecture target with the GOOS and GOARCH environment variables:
You might also want to set the filename of the output executable manually to keep track of the
architecture:
https://riptutorial.com/ 58
From version 1.7 and onwards you can get a list of all possible GOOS and GOARCH
combinations with:
Installation
The installation is done very easily by executing go get github.com/mitchellh/gox. The resulting
executable gets placed at Go's binary directory, e.g. /golang/bin or ~/golang/bin. Ensure that this
folder is part of your path in order to use the gox command from an arbitrary location.
Usage
From within a Go project's root folder (where you perform e.g. go build), execute gox in order to
build all possible binaries for any architecture (e.g. x86, ARM) and operating system (e.g. Linux,
macOS, Windows) which is available.
In order to build for a certain operating system, use e.g. gox -os="linux" instead. Also the
architecture option could be defined: gox -osarch="linux/amd64".
package main
import "fmt"
func main(){
fmt.Println("hello world")
}
https://riptutorial.com/ 59
www.dbooks.org
Chapter 16: Cryptography
Introduction
Find out how to encrypt and decrypt data with Go. Keep in mind that this is not a course about
cryptography but rather how to achieve it with Go.
Examples
Encryption and decryption
Foreword
This is a detailed example about how to encrypt and decrypt data with Go. The uses code is
shorten, e.g. the error handling is not mentioned. The full working project with error handling and
user interface could be found on Github here.
Encryption
Introduction and data
This example describes a full working encryption and decryption in Go. In order to do so, we need
a data. In this example, we use our own data structure secret:
https://riptutorial.com/ 60
Next, we want to encrypt such a secret. The full working example could be found here (link to
Github). Now, the step-by-step process:
Step 1
First of all, we need a kind of master password to protected the secret: masterPassword := "PASS"
Step 2
All the crypto methods working with bytes instead of strings. Thus, we construct a byte array with
the data from our secret.
secretBytesDecrypted :=
[]byte(fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
artifact.DisplayName,
strings.Replace(artifact.Notes, "\n", string(65000), -1),
artifact.Username,
artifact.EMail,
artifact.CopyMethod,
artifact.Password,
artifact.CustomField01Name,
artifact.CustomField01Data,
artifact.CustomField02Name,
artifact.CustomField02Data,
artifact.CustomField03Name,
artifact.CustomField03Data,
artifact.CustomField04Name,
artifact.CustomField04Data,
artifact.CustomField05Name,
artifact.CustomField05Data,
artifact.CustomField06Name,
artifact.CustomField06Data,
))
Step 3
We create some salt in order to prevent rainbow table attacks, cf. Wikipedia: saltBytes :=
uuid.NewV4().Bytes(). Here, we use an UUID v4 which is not predictable.
Step 4
Now, we are able to derive a key and a vector out of the master password and the random salt,
regarding RFC 2898:
keyLength := 256
rfc2898Iterations := 6
https://riptutorial.com/ 61
www.dbooks.org
Step 5
The desired CBC mode works with whole blocks. Thus, we have to check if our data is aligned to
a full block. If not, we have to pad it:
if len(secretBytesDecrypted)%aes.BlockSize != 0 {
numberNecessaryBlocks := int(math.Ceil(float64(len(secretBytesDecrypted)) /
float64(aes.BlockSize)))
enhanced := make([]byte, numberNecessaryBlocks*aes.BlockSize)
copy(enhanced, secretBytesDecrypted)
secretBytesDecrypted = enhanced
}
Step 6
Now we create an AES cipher: aesBlockEncrypter, aesErr := aes.NewCipher(keyBytes)
Step 7
We reserve the necessary memory for the encrypted data: encryptedData := make([]byte,
len(secretBytesDecrypted)). In case of AES-CBC, the encrypted data had the same length as the
unencrypted data.
Step 8
Now, we should create the encrypter and encrypt the data:
Step 9
The encrypted data must be stored. But not only the data: Without the salt, the encrypted data
could not be decrypted. Thus, we must use some kind of file format to manage this. Here, we
encode the encrypted data as base64, cf. Wikipedia:
Next, we define our file content and our own file format. The format looks like this: salt[0x10]base64
content. First, we store the salt. In order to mark the beginning of the base64 content, we store the
byte 10. This works, because base64 does not use this value. Therefore, we could find the start of
base64 by search the first occurrence of 10 from the end to the beginning of the file.
https://riptutorial.com/ 62
fileContent := make([]byte, len(saltBytes))
copy(fileContent, saltBytes)
fileContent = append(fileContent, 10)
fileContent = append(fileContent, encodedBytes...)
Step 10
Finally, we could write our file: writeErr := ioutil.WriteFile("my secret.data", fileContent, 0644).
Decryption
Introduction and data
As for encryption, we need some data to work with. Thus, we assume we have an encrypted file
and the mentioned structure secret. The goal is to read the encrypted data from the file, decrypt it,
and create an instance of the structure.
Step 1
The first step is identical to the encryption: We need a kind of master password to decrypt the
secret: masterPassword := "PASS".
Step 2
Now, we read the encrypted data from file: encryptedFileData, bytesErr :=
ioutil.ReadFile(filename).
Step 3
As mentioned before, we could split salt and encrypted data by the delimiter byte 10, searched
backwards from the end to the beginning:
Step 4
Next, we must decode the base64 encoded bytes:
https://riptutorial.com/ 63
www.dbooks.org
decodedBytes := make([]byte, len(encryptedBytesBase64))
countDecoded, decodedErr := base64.StdEncoding.Decode(decodedBytes, encryptedBytesBase64)
encryptedBytes = decodedBytes[:countDecoded]
Step 5
Now, we are able to derive a key and a vector out of the master password and the random salt,
regarding RFC 2898:
keyLength := 256
rfc2898Iterations := 6
Step 6
Create an AES cipher: aesBlockDecrypter, aesErr := aes.NewCipher(keyBytes).
Step 7
Reserve the necessary memory for the decrypted data: decryptedData := make([]byte,
len(encryptedBytes)). By definition, it has the same length as the encrypted data.
Step 8
Now, create the decrypter and decrypt the data:
Step 9
Convert the read bytes to string: decryptedString := string(decryptedData). Because we need
lines, split the string: lines := strings.Split(decryptedString, "\n").
Step 10
Construct a secret out of the lines:
artifact := secret{}
artifact.DisplayName = lines[0]
artifact.Notes = lines[1]
artifact.Username = lines[2]
https://riptutorial.com/ 64
artifact.EMail = lines[3]
artifact.CopyMethod = lines[4]
artifact.Password = lines[5]
artifact.CustomField01Name = lines[6]
artifact.CustomField01Data = lines[7]
artifact.CustomField02Name = lines[8]
artifact.CustomField02Data = lines[9]
artifact.CustomField03Name = lines[10]
artifact.CustomField03Data = lines[11]
artifact.CustomField04Name = lines[12]
artifact.CustomField04Data = lines[13]
artifact.CustomField05Name = lines[14]
artifact.CustomField05Data = lines[15]
artifact.CustomField06Name = lines[16]
artifact.CustomField06Data = lines[17]
Finally, re-create the line breaks within the notes field: artifact.Notes =
strings.Replace(artifact.Notes, string(65000), "\n", -1).
https://riptutorial.com/ 65
www.dbooks.org
Chapter 17: Defer
Introduction
A defer statement pushes a function call onto a list. The list of saved calls is executed after the
surrounding function returns. Defer is commonly used to simplify functions that perform various
clean-up actions.
Syntax
• defer someFunc(args)
• defer func(){ //code goes here }()
Remarks
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).
Examples
Defer Basics
A defer statement in Go is simply a function call marked to be executed at a later time. Defer
statement is an ordinary function call prefixed by the keyword defer.
defer someFunction()
A deferred function is executed once the function that contains the defer statement returns. Actual
call to the deferred function occurs when the enclosing function:
Example:
func main() {
fmt.Println("First main statement")
defer logExit("main") // position of defer statement here does not matter
fmt.Println("Last main statement")
}
https://riptutorial.com/ 66
}
Output:
If a function has multiple deferred statements, they form a stack. The last defer is the first one to
execute after the enclosing function returns, followed by subsequent calls to preceding defers in
order (below example returns by causing a panic):
func main() {
defer logNum(1)
fmt.Println("First main statement")
defer logNum(2)
defer logNum(3)
panic("panic occurred")
fmt.Println("Last main statement") // not printed
defer logNum(3) // not deferred since execution flow never reaches this line
}
Output:
goroutine 1 [running]:
....
Note that deferred functions have their arguments evaluated at the time defer executes:
func main() {
i := 1
defer logNum(i) // deferred function call: logNum(1)
fmt.Println("First main statement")
i++
defer logNum(i) // deferred function call: logNum(2)
defer logNum(i*i) // deferred function call: logNum(4)
return // explicit return
}
Output:
https://riptutorial.com/ 67
www.dbooks.org
First main statement
Num 4
Num 2
Num 1
If a function has named return values, a deferred anonymous function within that function can
access and update the returned value even after the function has returned:
func main() {
fmt.Println(plusOne(1)) // 2
return
}
Finally, a defer statement is generally used operations that often occur together. For example:
This use ensures proper release of system resources irrespective of the flow of execution.
Deferred function calls serve a similar purpose to things like finally blocks in languages like Java:
they ensure that some function will be executed when the outer function returns, regardless of if
an error occurred or which return statement was hit in cases with multiple returns. This is useful for
cleaning up resources that must be closed like network connections or file pointers. The defer
keyword indicates a deferred function call, similarly to the go keyword initiating a new goroutine.
Like a go call, function arguments are evaluated immediately, but unlike a go call, deferred
functions are not executed concurrently.
func MyFunc() {
conn := GetConnection() // Some kind of connection that must be closed.
defer conn.Close() // Will be executed when MyFunc returns, regardless of how.
// Do some things...
if someCondition {
return // conn.Close() will be called
https://riptutorial.com/ 68
}
// Do more things
}// Implicit return - conn.Close() will still be called
Note the use of conn.Close() instead of conn.Close - you're not just passing in a function, you're
deferring a full function call, including its arguments. Multiple function calls can be deferred in the
same outer function, and each will be executed once in reverse order. You can also defer closures
- just don't forget the parens!
defer func(){
// Do some cleanup
}()
https://riptutorial.com/ 69
www.dbooks.org
Chapter 18: Developing for Multiple Platforms
with Conditional Compiling
Introduction
Platform based conditional compiling comes in two forms in Go, one is with file suffixes and the
other is with build tags.
Syntax
• After "// +build", a single platform or a list can follow
• Platform can be reverted by preceding it by ! sign
• List of space separated platforms are ORed together
Remarks
Caveats for build tags:
• The // +build constraint must be placed at the top of the file, even before package clause.
• It must be followed by one blank line to separate from package comments.
List of valid platforms for both build tags and file suffixes
android
darwin
dragonfly
freebsd
linux
netbsd
openbsd
plan9
solaris
windows
https://riptutorial.com/ 70
Examples
Build tags
// +build linux
package lib
// +build !windows
package lib
var NotWindows int // Will be compiled in all platforms but not Windows
package lib
var SomeUnix int // Will be compiled in linux, darwin and plan9 but not on others
File suffix
If you name your file lib_linux.go, all the content in that file will only be compiled in linux
environments:
package lib
Different platforms can have separate implementations of the same method. This example also
illustrates how build tags and file suffixes can be used together.
File main.go:
package main
import "fmt"
func main() {
fmt.Println("Hello World from Conditional Compilation Doc!")
printDetails()
}
https://riptutorial.com/ 71
www.dbooks.org
details.go:
// +build !windows
package main
import "fmt"
func printDetails() {
fmt.Println("Some specific details that cannot be found on Windows")
}
details_windows.go:
package main
import "fmt"
func printDetails() {
fmt.Println("Windows specific details")
}
https://riptutorial.com/ 72
Chapter 19: Error Handling
Introduction
In Go, unexpected situations are handled using errors, not exceptions. This approach is more
similar to that of C, using errno, than to that of Java or other object-oriented languages, with their
try/catch blocks. However, an error is not an integer but an interface.
A function that may fail typically returns an error as its last return value. If this error is not nil,
something went wrong, and the caller of the function should take action accordingly.
Remarks
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.
Examples
Creating an error value
errors.New("this is an error")
If you want to add additional information to an error, the fmt package also provides a useful error
creation method:
var f float64
fmt.Errorf("error with some additional information: %g", f)
package main
https://riptutorial.com/ 73
www.dbooks.org
import (
"errors"
"fmt"
)
func main() {
fmt.Println(DoSomething(1)) // succeeds! returns nil
fmt.Println(DoSomething(2)) // returns a specific error message
fmt.Println(DoSomething(3)) // returns an error variable
fmt.Println(DoSomething(4)) // returns a simple error message
}
Open in Playground
In Go, an error is represented by any value that can describe itself as string. Any type that
implement the built-in error interface is an error.
The following example shows how to define a new error type using a string composite literal.
package main
https://riptutorial.com/ 74
import (
"fmt"
)
func main() {
fmt.Println(DoSomething(1)) // succeeds! returns nil
fmt.Println(DoSomething(2)) // returns an error message
}
// do something here
Returning an error
In Go you don't raise an error. Instead, you return an error in case of failure.
If the method returns multiple values (and the execution can fail), then the standard convention is
to return the error as the last argument.
https://riptutorial.com/ 75
www.dbooks.org
}
s := "Success!"
Handling an error
In Go errors can be returned from a function call. The convention is that if a method can fail, the
last returned argument is an error.
If you are not interested in the error, you can simply ignore it by assigning it to _.
result, _ := DoAndReturnSomething()
fmt.Println(result)
Of course, ignoring an error can have serious implications. Therefore, this is generally not
recommended.
If you have multiple method calls, and one or more methods in the chain may return an error, you
should propagate the error to the first level that can handle it.
https://riptutorial.com/ 76
if err != nil {
return "", err
}
A common mistake is to declare a slice and start requesting indexes from it without initializing it,
which leads to an "index out of range" panic. The following code explains how to recover from the
panic without exiting the program, which is the normal behavior for a panic. In most situations,
returning an error in this fashion rather than exiting the program on a panic is only useful for
development or testing purposes.
func main() {
fp := &Foo{}
if err := fp.Panic(); err != nil {
fmt.Printf("Error: %v", err)
}
fmt.Println("ok")
}
if r := recover(); r != nil {
if _, ok := r.(runtime.Error); ok {
//fmt.Println("Panicing")
//panic(r)
*err = r.(error)
} else {
*err = r.(error)
}
}
}
The use of a separate function (rather than closure) allows re-use of the same function in other
functions prone to panic.
https://riptutorial.com/ 77
www.dbooks.org
Read Error Handling online: https://riptutorial.com/go/topic/785/error-handling
https://riptutorial.com/ 78
Chapter 20: Executing Commands
Examples
Timing Out with Interrupt and then Kill
c := exec.Command(name, arg...)
b := &bytes.Buffer{}
c.Stdout = b
c.Stdin = stdin
if err := c.Start(); err != nil {
return nil, err
}
timedOut := false
intTimer := time.AfterFunc(timeout, func() {
log.Printf("Process taking too long. Interrupting: %s %s", name, strings.Join(arg, " "))
c.Process.Signal(os.Interrupt)
timedOut = true
})
killTimer := time.AfterFunc(timeout*2, func() {
log.Printf("Process taking too long. Killing: %s %s", name, strings.Join(arg, " "))
c.Process.Signal(os.Kill)
timedOut = true
})
err := c.Wait()
intTimer.Stop()
killTimer.Stop()
if timedOut {
log.Print("the process timed out\n")
}
https://riptutorial.com/ 79
www.dbooks.org
log.Printf("Command finished with error: %v", err)
A Cmd cannot be reused after calling its Run, Output or CombinedOutput methods
Rather, one must use two separate exec.Command. You might also need some delay between
commands.
https://riptutorial.com/ 80
Chapter 21: File I/O
Syntax
• file, err := os.Open(name) // Opens a file in read-only mode. A non-nil error is returned if the
file could not be opened.
• file, err := os.Create(name) // Creates or opens a file if it already exists in write-only mode.
The file is overwritten to if it already exists. A non-nil error is returned if the file could not be
opened.
• file, err := os.OpenFile(name, flags, perm) // Opens a file in the mode specified by the flags.
A non-nil error is returned if the file could not be opened.
• data, err := ioutil.ReadFile(name) // Reads the entire file and returns it. A non-nil error is
returned if the entire file could not be read.
• err := ioutil.WriteFile(name, data, perm) // Creates or overwrites a file with the provided data
and UNIX permission bits. A non-nil error is returned if the file failed to be written to.
• err := os.Remove(name) // Deletes a file. A non-nil error is returned if the file could not be
deleted.
• err := os.RemoveAll(name) // Deletes a file or whole directory hierarchy. A non-nil error is
returned if the file or directory could not be deleted.
• err := os.Rename(oldName, newName) // Renames or moves a file (can be across
directories). A non-nil error is returned if the file could not be moved.
Parameters
Parameter Details
An error. If not nil, it represents an error that occurred when the function was
err
called.
A file handler of type *os.File returned by the os package file related functions.
It implements an io.ReadWriter, meaning you can call Read(data) and Write(data)
file
on it. Note that these functions may not be able to be called depending on the
open flags of the file.
The UNIX permission bits used to open a file with of type os.FileMode. Several
perm
constants are available to help with the use of permission bits.
File open flags that determine the methods that can be called on the file handler
of type int. Several constants are available to help with the use of flags. They
flag
are: os.O_RDONLY, os.O_WRONLY, os.O_RDWR, os.O_APPEND, os.O_CREATE, os.O_EXCL,
os.O_SYNC, and os.O_TRUNC.
https://riptutorial.com/ 81
www.dbooks.org
Examples
Reading and writing to a file using ioutil
A simple program that writes "Hello, world!" to test.txt, reads back the data, and prints it out.
Demonstrates simple file I/O operations.
package main
import (
"fmt"
"io/ioutil"
)
func main() {
hello := []byte("Hello, world!")
// Write `Hello, world!` to test.txt that can read/written by user and read by others
err := ioutil.WriteFile("test.txt", hello, 0644)
if err != nil {
panic(err)
}
// Read test.txt
data, err := ioutil.ReadFile("test.txt")
if err != nil {
panic(err)
}
package main
import (
"fmt"
"io/ioutil"
)
func main() {
files, err := ioutil.ReadDir(".")
if err != nil {
panic(err)
}
https://riptutorial.com/ 82
Listing all folders in the current directory
package main
import (
"fmt"
"io/ioutil"
)
func main() {
files, err := ioutil.ReadDir(".")
if err != nil {
panic(err)
}
https://riptutorial.com/ 83
www.dbooks.org
Chapter 22: Fmt
Examples
Stringer
The fmt.Stringer interface requires a single method, String() string to be satisfied. The string
method defines the "native" string format for that value, and is the default representation if the
value is provided to any of the fmt packages formatting or printing routines.
package main
import (
"fmt"
)
func main() {
u := User{
Name: "John Doe",
Email: "[email protected]",
}
fmt.Println(u)
// output: John Doe <[email protected]>
}
Playground
Basic fmt
Format Functions
There are 4 main function types in fmt and several variations within.
https://riptutorial.com/ 84
Print
Sprint
Fprint
Scan
Scan scans text read from standard input.
var s string
fmt.Scanln(&s) // pass pointer to buffer
// Scanln is similar to fmt.Scan(), but it stops scanning at new line.
fmt.Println(s) // whatever was inputted
Stringer Interface
Any value which has a String() method implements the fmt inteface Stringer
https://riptutorial.com/ 85
www.dbooks.org
Chapter 23: Functions
Introduction
Functions in Go provide organized, reusable code to perform a set of actions. Functions simplify
the coding process, prevent redundant logic, and make code easier to follow. This topic describes
the declaration and utilization of functions, arguments, parameters, return statements and scopes
in Go.
Syntax
• func() // function type with no arguments and no return value
• func(x int) int // accepts integer and returns an integer
• func(a, b int, z float32) bool // accepts 2 integers, one float and returns a boolean
• func(prefix string, values ...int) // "variadic" function which accepts one string and one or
more number of integers
• func() (int, bool) // function returning two values
• func(a, b int, z float64, opt ...interface{}) (success bool) // accepts 2 integers, one float and
one or more number of interfaces and returns named boolean value (which is already
initialized inside of function)
Examples
Basic Declaration
A simple function that does not accept any parameters and does not return any values:
func SayHello() {
fmt.Println("Hello!")
}
Parameters
Notice that the type for firstName is omitted because it is identical to lastName.
Return Values
https://riptutorial.com/ 86
func AddAndMultiply(a, b int) (int, int) {
return a+b, a*b
}
import errors
Return values can be assigned to a local variable. An empty return statement can then be used to
return their current values. This is known as "naked" return. Naked return statements should be
used only in short functions as they harm readability in longer functions:
play it on playground
play it on playground
https://riptutorial.com/ 87
www.dbooks.org
A simple literal function, printing Hello! to stdout:
package main
import "fmt"
func main() {
func(){
fmt.Println("Hello!")
}()
}
play it on playground
package main
import "fmt"
func main() {
func(str string) {
fmt.Println(str)
}("Hello!")
}
play it on playground
package main
import "fmt"
func main() {
str := "Hello!"
func() {
fmt.Println(str)
}()
}
play it on playground
package main
import (
"fmt"
)
func main() {
https://riptutorial.com/ 88
str := "Hello!"
anon := func() {
fmt.Println(str)
}
anon()
}
play it on playground
Variadic functions
A variadic function can be called with any number of trailing arguments. Those elements are
stored in a slice.
package main
import "fmt"
func main() {
variadic("Hello", "Goodbye")
variadic("Str1", "Str2", "Str3")
}
play it on playground
func main() {
strs := []string {"Str1", "Str2", "Str3"}
variadic(strs...)
}
play it on playground
https://riptutorial.com/ 89
www.dbooks.org
Chapter 24: Getting Started With Go Using
Atom
Introduction
After installing go (http://www.riptutorial.com/go/topic/198/getting-started-with-go ) you'll need an
environment. An efficient and free way to get you started is using Atom text editor (https://atom.io )
and gulp. A question that maybe crossed your mind is why use gulp?.We need gulp for auto-
completion. Let's get Started!
Examples
Get, Install And Setup Atom & Gulp
https://riptutorial.com/ 90
3. Get these dependencies using go get or another dependency manager: (open a console and
run these commands)
go get -u golang.org/x/tools/cmd/goimports
https://riptutorial.com/ 91
www.dbooks.org
go get -u golang.org/x/tools/cmd/gorename
go get -u github.com/sqs/goreturns
go get -u github.com/nsf/gocode
go get -u github.com/alecthomas/gometalinter
go get -u github.com/zmb3/gogetdoc
go get -u github.com/rogpeppe/godef
go get -u golang.org/x/tools/cmd/guru
4. Install Gulp (Gulpjs) using npm or any other package manager (gulp-getting-started-doc):
Create $GO_PATH/gulpfile.js
gulp.task('compilepkg', function() {
return gulp.src(goPath, {read: false})
.pipe(shell(['go install <%= stripPath(file.path) %>'],
{
templateData: {
stripPath: function(filePath) {
var subPath = filePath.substring(process.cwd().length + 5);
var pkg = subPath.substring(0, subPath.lastIndexOf(path.sep));
return pkg;
}
}
})
);
});
gulp.task('watch', function() {
gulp.watch(goPath, ['compilepkg']);
});
In the code above we defined a compliepkg task that will be triggered every time any go file in
goPath (src/mypackage/) or subdirectories changes. the task will run the shell command go install
changed_file.go
After creating the gulp file in go path and define the task open a command line and run:
gulp watch
https://riptutorial.com/ 92
Create $GO_PATH/mypackage/source.go
package mypackage
Creating $GO_PATH/main.go
Now you can start writing your own go code with auto-completion using Atom and Gulp:
https://riptutorial.com/ 93
www.dbooks.org
https://riptutorial.com/ 94
package main
import (
"fmt"
https://riptutorial.com/ 95
www.dbooks.org
"mypackage"
)
func main() {
https://riptutorial.com/ 96
Chapter 25: gob
Introduction
Gob is a Go specific serialisation method. it has support for all Go data types except for channels
and functions. Gob also encodes the type information into the serialised form, what makes it
different from say XML is that it is much more efficient.
The inclusion of type information makes encoding and decoding fairly robust to differences
between encoder and decoder.
Examples
How to encode data and write to file with gob?
package main
import (
"encoding/gob"
"os"
)
func main() {
user := User{
"zola",
"supersecretpassword",
}
file, _ := os.Create("user.gob")
defer file.Close()
encoder := gob.NewEncoder(file)
encoder.Encode(user)
package main
import (
"encoding/gob"
"fmt"
"os"
https://riptutorial.com/ 97
www.dbooks.org
)
func main() {
user := User{}
file, _ := os.Open("user.gob")
defer file.Close()
decoder := gob.NewDecoder(file)
decoder.Decode(&user)
fmt.Println(user)
package main
import (
"encoding/gob"
"fmt"
"os"
)
func main() {
user := User{
https://riptutorial.com/ 98
"zola",
"supersecretpassword",
}
admin := Admin{
"john",
"supersecretpassword",
true,
}
file, _ := os.Create("user.gob")
adminFile, _ := os.Create("admin.gob")
defer file.Close()
defer adminFile.Close()
encoder := gob.NewEncoder(file)
adminEncoder := gob.NewEncoder(adminFile)
InterfaceEncode(encoder, user)
InterfaceEncode(adminEncoder, admin)
package main
import (
"encoding/gob"
"fmt"
"log"
"os"
)
https://riptutorial.com/ 99
www.dbooks.org
IsAdmin bool
}
func main() {
file, _ := os.Open("user.gob")
adminFile, _ := os.Open("admin.gob")
defer file.Close()
defer adminFile.Close()
userDecoder := gob.NewDecoder(file)
adminDecoder := gob.NewDecoder(adminFile)
user = InterfaceDecode(userDecoder)
admin = InterfaceDecode(adminDecoder)
fmt.Println(user)
fmt.Println(admin)
var d Deleter
return d
https://riptutorial.com/ 100
Chapter 26: Goroutines
Introduction
A goroutine is a lightweight thread managed by the Go runtime.
go f(x, y, z)
f(x, y, z)
The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in
the new goroutine.
Goroutines run in the same address space, so access to shared memory must be synchronized.
The sync package provides useful primitives, although you won't need them much in Go as there
are other primitives.
Reference: https://tour.golang.org/concurrency/1
Examples
Goroutines Basic Program
package main
import (
"fmt"
"time"
)
func main() {
go say("world")
say("hello")
}
A goroutine is a function that is capable of running concurrently with other functions. To create a
goroutine we use the keyword go followed by a function invocation:
package main
import "fmt"
https://riptutorial.com/ 101
www.dbooks.org
func f(n int) {
for i := 0; i < 10; i++ {
fmt.Println(n, ":", i)
}
}
func main() {
go f(0)
var input string
fmt.Scanln(&input)
}
Generally, function call executes all the statements inside the function body and return to the next
line. But, with goroutines we return immediately to the next line as it don't wait for the function to
complete. So, a call to a Scanln function included, otherwise the program has been exited without
printing the numbers.
https://riptutorial.com/ 102
Chapter 27: HTTP Client
Syntax
• resp, err := http.Get(url) // Makes a HTTP GET request with the default HTTP client. A non-
nil error is returned if the request fails.
• resp, err := http.Post(url, bodyType, body) // Makes a HTTP POST request with the default
HTTP client. A non-nil error is returned if the request fails.
• resp, err := http.PostForm(url, values) // Makes a HTTP form POST request with the default
HTTP client. A non-nil error is returned if the request fails.
Parameters
Parameter Details
An error. If not nil, it represents an error that occured when the function was
err
called.
bodyType The MIME type of type string of the body payload of a POST request.
Remarks
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.
Examples
Basic GET
Perform a basic GET request and prints the contents of a site (HTML).
package main
import (
https://riptutorial.com/ 103
www.dbooks.org
"fmt"
"io/ioutil"
"net/http"
)
func main() {
resp, err := http.Get("https://example.com/")
if err != nil {
panic(err)
}
A request for the top 10 most recently active StackOverflow posts using the Stack Exchange API.
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
)
func main() {
// Set URL parameters on declaration
values := url.Values{
"order": []string{"desc"},
"sort": []string{"activity"},
"site": []string{"stackoverflow"},
}
https://riptutorial.com/ 104
resp, err := http.Get(apiURL + values.Encode())
if err != nil {
panic(err)
}
defer resp.Body.Close()
// To compare status codes, you should always use the status constants
// provided by the http package.
if resp.StatusCode != http.StatusOK {
panic("Request was not OK: " + resp.Status)
}
1.7+
Timing out an HTTP request with a context can be accomplished with only the standard library
(not the subrepos) in 1.7+:
import (
"context"
"net/http"
"time"
)
Before 1.7
import (
"net/http"
"time"
"golang.org/x/net/context"
https://riptutorial.com/ 105
www.dbooks.org
"golang.org/x/net/context/ctxhttp"
)
Further Reading
For more information on the context package see Context.
The following updates a User object via a PUT request and prints the status code of the request:
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
func main() {
user := User{
Name: "John Doe",
Email: "[email protected]",
}
https://riptutorial.com/ 106
}
fmt.Println(resp.StatusCode)
}
https://riptutorial.com/ 107
www.dbooks.org
Chapter 28: HTTP Server
Remarks
http.ServeMux provides a multiplexer which calls handlers for HTTP requests.
• Gorilla Mux
Examples
HTTP Hello World with custom server and mux
package main
import (
"log"
"net/http"
)
func main() {
Hello World
The typical way to begin writing webservers in golang is to use the standard library net/http
module.
The following code also uses it. Here is the simplest possible HTTP server implementation. It
https://riptutorial.com/ 108
responds "Hello World" to any HTTP request.
package main
import (
"log"
"net/http"
)
func main() {
// All URLs will be handled by this function
// http.HandleFunc uses the DefaultServeMux
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, world!"))
})
$ go run server.go
$ go build server.go
$ ./server
The server will listen to the specified port (:8080). You can test it with any HTTP client. Here's an
example with cURL:
curl -i http://localhost:8080/
HTTP/1.1 200 OK
Date: Wed, 20 Jul 2016 18:04:46 GMT
Content-Length: 13
Content-Type: text/plain; charset=utf-8
Hello, world!
HandleFunc registers the handler function for the given pattern in the server mux (router).
You can pass define an anonymous function, as we have seen in the basic Hello World example:
https://riptutorial.com/ 109
www.dbooks.org
But we can also pass a HandlerFunc type. In other words, we can pass any function that respects
the following signature:
We can rewrite the previous example passing the reference to a previously defined HandlerFunc.
Here's the full example:
package main
import (
"fmt"
"net/http"
)
// A HandlerFunc function
// Notice the signature of the function
func RootHandler(w http.ResponseWriter, req *http.Request) {
fmt.Fprintln(w, "Hello, world!")
}
func main() {
// Here we pass the reference to the `RootHandler` handler function
http.HandleFunc("/", RootHandler)
panic(http.ListenAndServe(":8080", nil))
}
Of course, you can define several function handlers for different paths.
package main
import (
"fmt"
"log"
"net/http"
)
func main() {
http.HandleFunc("/foo", FooHandler)
http.HandleFunc("/bar", BarHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
➜ ~ curl -i localhost:8080/foo
HTTP/1.1 200 OK
https://riptutorial.com/ 110
Date: Wed, 20 Jul 2016 18:23:08 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8
➜ ~ curl -i localhost:8080/bar
HTTP/1.1 200 OK
Date: Wed, 20 Jul 2016 18:23:10 GMT
Content-Length: 16
Content-Type: text/plain; charset=utf-8
➜ ~ curl -i localhost:8080/
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Wed, 20 Jul 2016 18:23:13 GMT
Content-Length: 19
Generate a certificate
In order to run a HTTPS server, a certificate is necessary. Generating a self-signed certificate with
openssl is done by executing this command:
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout key.pem -out cert.pem -subj
"/CN=example.com" -days 3650`
Note: A self-signed certificate could be used e.g. for internal projects, debugging, testing, etc. Any
browser out there will mention, that this certificate is not safe. In order to avoid this, the certificate
must signed by a certification authority. Mostly, this is not available for free. One exception is the
https://riptutorial.com/ 111
www.dbooks.org
"Let's Encrypt" movement: https://letsencrypt.org
package main
import (
"log"
"net/http"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, world!"))
})
log.Fatal(http.ListenAndServeTLS(":443","cert.pem","key.pem", nil))
}
Responses can be written to a http.ResponseWriter using templates in Go. This proves as a handy
tool if you wish to create dynamic pages.
(To learn how Templates work in Go, please visit the Go Templates Documentation page.)
Continuing with a simple example to utilise the html/template to respond to an HTTP Request:
package main
import(
"html/template"
"net/http"
"log"
)
func main(){
http.HandleFunc("/",WelcomeHandler)
http.ListenAndServe(":8080",nil)
}
https://riptutorial.com/ 112
func WelcomeHandler(w http.ResponseWriter, r *http.Request){
if r.Method == "GET"{
t,err := template.ParseFiles("welcomeform.html")
check(err)
t.Execute(w,nil)
}else{
r.ParseForm()
myUser := User{}
myUser.Name = r.Form.Get("entered_name")
myUser.nationality = r.Form.Get("entered_nationality")
t, err := template.ParseFiles("welcomeresponse.html")
check(err)
t.Execute(w,myUser)
}
}
1. welcomeform.html are:
<head>
<title> Help us greet you </title>
</head>
<body>
<form method="POST" action="/">
Enter Name: <input type="text" name="entered_name">
Enter Nationality: <input type="text" name="entered_nationality">
<input type="submit" value="Greet me!">
</form>
</body>
1. welcomeresponse.html are:
<head>
<title> Greetings, {{.Name}} </title>
</head>
<body>
Greetings, {{.Name}}.<br>
We know you are a {{.nationality}}!
</body>
Note:
1. Make sure that the .html files are in the correct directory.
3. As it can be seen after submitting the form, the unexported nationality field of the struct could
not be parsed by the template package, as expected.
https://riptutorial.com/ 113
www.dbooks.org
package main
import (
"net/http"
)
func main() {
muxer := http.NewServeMux()
fileServerCss := http.FileServer(http.Dir("src/css"))
fileServerJs := http.FileServer(http.Dir("src/js"))
fileServerHtml := http.FileServer(http.Dir("content"))
muxer.Handle("/", fileServerHtml)
muxer.Handle("/css", fileServerCss)
muxer.Handle("/js", fileServerJs)
http.ListenAndServe(":8080", muxer)
}
Here are a simple example of some common tasks related to developing an API, differentiating
between the HTTP Method of the request, accessing query string values and accessing the
request body.
Resources
• http.Handler interface
• http.ResponseWriter
• http.Request
• Available Method and Status constants
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
// ParseForm will parse query string values and make r.Form available
r.ParseForm()
switch r.Method {
case http.MethodGet:
// Handle GET requests
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("Query string values: %s", queryMap)))
return
https://riptutorial.com/ 114
case http.MethodPost:
// Handle POST requests
body, err := ioutil.ReadAll(r.Body)
if err != nil {
// Error occurred while parsing request body
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("Query string values: %s\nBody posted: %s", queryMap,
body)))
return
}
// Other HTTP methods (eg PUT, PATCH, etc) are not handled by the above
// so inform the client with appropriate status code
w.WriteHeader(http.StatusMethodNotAllowed)
}
func main() {
// All URLs will be handled by this function
// http.Handle, similarly to http.HandleFunc
// uses the DefaultServeMux
http.Handle("/", customHandler{})
https://riptutorial.com/ 115
www.dbooks.org
Chapter 29: Images
Introduction
The image package provides basic functionalities for working with 2-D image. This topic describes
several basic operations when working with image such as reading and writing a particular image
format, cropping, accessing and modifying pixel, color conversion, resizing and basic image
filtering.
Examples
Basic concepts
An image represents a rectangular grid of picture elements (pixel). In the image package, the pixel
is represented as one of the color defined in image/color package. The 2-D geometry of the image
is represented as image.Rectangle, while image.Point denotes a position on the grid.
The above figure illustrates the basic concepts of an image in the package. An image of size
15x14 pixels has a rectangular bounds started at upper left corner (e.g. co-ordinate (-3, -4) in the
above figure), and its axes increase right and down to lower right corner (e.g. co-ordinate (12, 10)
in the figure). Note that the bounds do not necessarily start from or contain point (0,0).
https://riptutorial.com/ 116
Image related type
In Go, an image always implement the following image.Image interface
// Corner co-ordinates
top := b.Min.Y
left := b.Min.X
bottom := b.Max.Y
right := b.Max.X
https://riptutorial.com/ 117
www.dbooks.org
for y := top; y < bottom; y++ {
for x := left; x < right; x++ {
cl := img.At(x, y)
r, g, b, a := cl.RGBA()
// do something with r,g,b,a color component
}
}
Note that in the package, the value of each R,G,B,A component is between 0-65535 (0x0000 - 0xffff
), not 0-255.
In memory, an image can be seen as a matrix of pixel (color). However, when an image being
stored in a permanent storage, it may be stored as is (RAW format), Bitmap or other image
formats with particular compression algorithm for saving storage space, e.g. PNG, JPEG, GIF, etc.
When loading an image with particular format, the image must be decoded to image.Image with
corresponding algorithm. An image.Decode function declared as
is provided for this particular usage. In order to be able to handle various image formats, prior to
calling the image.Decode function, the decoder must be registered through image.RegisterFormat
function defined as
Currently, the image package supports three file formats: JPEG, GIF and PNG. To register a
decoder, add the following
to the application's main package. Somewhere in your code (not necessary in main package), to
load a JPEG image, use the following snippets:
f, err := os.Open("inputimage.jpg")
if err != nil {
// Handle error
}
defer f.Close()
https://riptutorial.com/ 118
Save to PNG
To save an image into particular format, the corresponding encoder must be imported explicitly,
i.e.
f, err := os.Create("outimage.png")
if err != nil {
// Handle error
}
defer f.Close()
If you want to specify compression level other than DefaultCompression level, create an encoder,
e.g.
enc := png.Encoder{
CompressionLevel: png.BestSpeed,
}
err := enc.Encode(f, img)
Save to JPEG
To save to jpeg format, use the following:
import "image/jpeg"
https://riptutorial.com/ 119
www.dbooks.org
Save to GIF
To save the image to GIF file, use the following snippets.
import "image/gif"
opt := gif.Options {
NumColors: 256,
// Add more parameters as needed
}
Cropping image
Most of image type in image package having SubImage(r Rectangle) Image method, except
image.Uniform. Based on this fact, We can implement a function to crop an arbitrary image as
follows
if p, ok := img.(CropableImage); ok {
// Call SubImage. This should be fast,
// since SubImage (usually) shares underlying pixel.
cropImg = p.SubImage(cropRect)
} else if cropRect = cropRect.Intersect(img.Bounds()); !cropRect.Empty() {
// If `img` does not implement `SubImage`,
// copy (and silently convert) the image portion to RGBA image.
rgbaImg := image.NewRGBA(cropRect)
for y := cropRect.Min.Y; y < cropRect.Max.Y; y++ {
for x := cropRect.Min.X; x < cropRect.Max.X; x++ {
rgbaImg.Set(x, y, img.At(x, y))
}
}
cropImg = rgbaImg
newImg = true
} else {
// Return an empty RGBA image
cropImg = &image.RGBA{}
https://riptutorial.com/ 120
newImg = true
}
Note that the cropped image may shared its underlying pixels with the original image. If this is the
case, any modification to the cropped image will affect the original image.
Some digital image processing algorithm such as edge detection, information carried by the image
intensity (i.e. grayscale value) is sufficient. Using color information (R, G, B channel) may provides
slightly better result, but the algorithm complexity will be increased. Thus, in this case, we need to
convert the color image to grayscale image prior to applying such algorithm.
The following code is an example of converting arbitrary image to 8-bit grayscale image. The
image is retrieved from remote location using net/http package, converted to grayscale, and finally
saved as PNG image.
package main
import (
"image"
"log"
"net/http"
"os"
_ "image/jpeg"
"image/png"
)
func main() {
// Load image from remote through http
// The Go gopher was designed by Renee French. (http://reneefrench.blogspot.com/)
// Images are available under the Creative Commons 3.0 Attributions license.
resp, err := http.Get("http://golang.org/doc/gopher/fiveyears.jpg")
if err != nil {
// handle error
log.Fatal(err)
}
defer resp.Body.Close()
https://riptutorial.com/ 121
www.dbooks.org
}
}
Color conversion occurs when assigning pixel through Set(x, y int, c color.Color) which is
implemented in image.go as
i := p.PixOffset(x, y)
p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
}
// These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
// as those given by the JFIF specification and used by func RGBToYCbCr in
// ycbcr.go.
//
// Note that 19595 + 38470 + 7471 equals 65536.
//
// The 24 is 16 + 8. The 16 is the same as used in RGBToYCbCr. The 8 is
// because the return value is 8 bit color, not 16 bit color.
y := (19595*r + 38470*g + 7471*b + 1<<15) >> 24
return Gray{uint8(y)}
}
Based on the above facts, the intensity Y is calculated with the following formula:
Mean: Y = (R + G + B) / 3
https://riptutorial.com/ 122
Luma: Y = 0.2126R + 0.7152G + 0.0722B
Luster: Y = (min(R, G, B) + max(R, G, B))/2
The above calculation is done by floating point multiplication, and certainly is not the most efficient
one, but it's enough for demonstrating the idea. The other point is, when calling Set(x, y int, c
color.Color) with color.Gray as third argument, the color model will not perform color conversion
as can be seen in the previous grayModel function.
https://riptutorial.com/ 123
www.dbooks.org
Chapter 30: Inline Expansion
Remarks
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):
Examples
Disabling inline expansion
Inline expansion can be disabled with the go:noinline pragma. For example, if we build the
following simple program:
package main
func printhello() {
println("Hello")
}
func main() {
printhello()
}
$ go version
go version go1.6.2 linux/amd64
$ go build main.go
$ ./main
Hello
$ go tool objdump main
https://riptutorial.com/ 124
TEXT main.main(SB) /home/sam/main.go
main.go:7 0x401000 64488b0c25f8ffffff FS MOVQ FS:0xfffffff8, CX
main.go:7 0x401009 483b6110 CMPQ 0x10(CX), SP
main.go:7 0x40100d 7631 JBE 0x401040
main.go:7 0x40100f 4883ec10 SUBQ $0x10, SP
main.go:8 0x401013 e8281f0200 CALL runtime.printlock(SB)
main.go:8 0x401018 488d1d01130700 LEAQ 0x71301(IP), BX
main.go:8 0x40101f 48891c24 MOVQ BX, 0(SP)
main.go:8 0x401023 48c744240805000000 MOVQ $0x5, 0x8(SP)
main.go:8 0x40102c e81f290200 CALL runtime.printstring(SB)
main.go:8 0x401031 e89a210200 CALL runtime.printnl(SB)
main.go:8 0x401036 e8851f0200 CALL runtime.printunlock(SB)
main.go:9 0x40103b 4883c410 ADDQ $0x10, SP
main.go:9 0x40103f c3 RET
main.go:7 0x401040 e87b9f0400 CALL
runtime.morestack_noctxt(SB)
main.go:7 0x401045 ebb9 JMP main.main(SB)
main.go:7 0x401047 cc INT $0x3
main.go:7 0x401048 cc INT $0x3
main.go:7 0x401049 cc INT $0x3
main.go:7 0x40104a cc INT $0x3
main.go:7 0x40104b cc INT $0x3
main.go:7 0x40104c cc INT $0x3
main.go:7 0x40104d cc INT $0x3
main.go:7 0x40104e cc INT $0x3
main.go:7 0x40104f cc INT $0x3
…
note that there is no CALL to printhello. However, if we then build the program with the pragma in
place:
package main
//go:noinline
func printhello() {
println("Hello")
}
func main() {
printhello()
}
$ go version
go version go1.6.2 linux/amd64
$ go build main.go
$ ./main
Hello
$ go tool objdump main
TEXT main.printhello(SB) /home/sam/main.go
main.go:4 0x401000 64488b0c25f8ffffff FS MOVQ FS:0xfffffff8, CX
main.go:4 0x401009 483b6110 CMPQ 0x10(CX), SP
main.go:4 0x40100d 7631 JBE 0x401040
main.go:4 0x40100f 4883ec10 SUBQ $0x10, SP
main.go:5 0x401013 e8481f0200 CALL runtime.printlock(SB)
main.go:5 0x401018 488d1d01130700 LEAQ 0x71301(IP), BX
main.go:5 0x40101f 48891c24 MOVQ BX, 0(SP)
https://riptutorial.com/ 125
www.dbooks.org
main.go:5 0x401023 48c744240805000000 MOVQ $0x5, 0x8(SP)
main.go:5 0x40102c e83f290200 CALL runtime.printstring(SB)
main.go:5 0x401031 e8ba210200 CALL runtime.printnl(SB)
main.go:5 0x401036 e8a51f0200 CALL runtime.printunlock(SB)
main.go:6 0x40103b 4883c410 ADDQ $0x10, SP
main.go:6 0x40103f c3 RET
main.go:4 0x401040 e89b9f0400 CALL
runtime.morestack_noctxt(SB)
main.go:4 0x401045 ebb9 JMP main.printhello(SB)
main.go:4 0x401047 cc INT $0x3
main.go:4 0x401048 cc INT $0x3
main.go:4 0x401049 cc INT $0x3
main.go:4 0x40104a cc INT $0x3
main.go:4 0x40104b cc INT $0x3
main.go:4 0x40104c cc INT $0x3
main.go:4 0x40104d cc INT $0x3
main.go:4 0x40104e cc INT $0x3
main.go:4 0x40104f cc INT $0x3
https://riptutorial.com/ 126
Chapter 31: Installation
Examples
Install in Linux or Ubuntu
Update $GOPATH
$ mkdir $HOME/go
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
$ nano ~/.bashrc
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
$ source ~/.bashrc
$ go version
go version go<version> linux/amd64
https://riptutorial.com/ 127
www.dbooks.org
Chapter 32: Installation
Remarks
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.
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
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.
https://riptutorial.com/ 128
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.
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.
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
https://riptutorial.com/ 129
www.dbooks.org
".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.
Examples
Example .profile or .bash_profile
https://riptutorial.com/ 130
Chapter 33: Interfaces
Remarks
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.
Examples
Simple interface
In Go, an interface is just a set of methods. We use an interface to specify a behavior of a given
object.
The implementing type need not declare that it is implementing the interface. It is enough to
define methods of the same signature.
var p Painter
p = Rembrandt{}
An interface can be satisfied (or implemented) by an arbitrary number of types. Also a type can
implement an arbitrary number of interfaces.
https://riptutorial.com/ 131
www.dbooks.org
func (h *Human) Write() {
fmt.Println("writing")
}
Here, The Human struct satisfy both the Singer and Writer interface, but the OnlySinger struct only
satisfy Singer interface.
Empty Interface
There is an empty interface type, that contains no methods. We declare it as interface{}. This
contains no methods so every type satisfies it. Hence empty interface can contain any type value.
var a interface{}
var i int = 5
s := "Hello world"
The most common use case for interfaces is to ensure that a variable supports one or more
behaviours. By contrast, the primary use case for the empty interface is to define a variable which
can hold any value, regardless of its concrete type.
i = a.(int)
s = a.(string)
m := a.(*StructType)
or
i, ok := a.(int)
s, ok := a.(string)
m, ok := a.(*StructType)
ok indicates if the interface a is convertible to given type. If it is not possible to cast ok will be false
.
https://riptutorial.com/ 132
Interface Values
If you declare a variable of an interface, it may store any value type that implements the methods
declared by the interface!
If we declare h of interface Singer, it may store a value of type Human or OnlySinger. This is
because of the fact that they all implement methods specified by the Singer interface.
var h Singer
h = &human{}
h.Sing()
In go it can sometimes be useful to know which underlying type you have been passed. This can
be done with a type switch. This assumes we have two structs:
One way to ask the compiler to check that the type T implements the interface I is by attempting
an assignment using the zero value for T or pointer to T, as appropriate. And we may choose to
https://riptutorial.com/ 133
www.dbooks.org
assign to the blank identifier to avoid unnecessary garbage:
type T struct{}
This question also appears in the official FAQ: How can I guarantee my type satisfies an
interface?
Type switch
Type switches can also be used to get a variable that matches the type of the case:
Type Assertion
You can access the real data type of interface with Type Assertion.
interfaceVariable.(DataType)
package main
import (
"fmt"
)
https://riptutorial.com/ 134
return a - b;
}
func main() {
var interfaceVar Subber = &MyType{}
fmt.Println(interfaceVar.Sub(6,5))
fmt.Println(interfaceVar.(*MyType).Msg)
}
Without .(*MyType) we wouldn't able to access Msg Field. If we try interfaceVar.Msg it will show
compile error:
In mathematics, especially Set Theory, we have a collection of things which is called set and we
name those things as elements. We show a set with its name like A, B, C, ... or explicitly with
putting its member on brace notation: {a, b, c, d, e}. Suppose we have an arbitrary element x and
a set Z, The key question is: "How we can understand that x is member of Z or not?".
Mathematician answer to this question with a concept: Characteristic Property of a set.
Characteristic Property of a set is an expression which describe set completely. For example we
have set of Natural Numbers which is {0, 1, 2, 3, 4, 5, ...}. We can describe this set with this
expression: {an | a0 = 0, an = an-1+1}. In last expression a0 = 0, an = an-1+1 is the characteristic
property of set of natural numbers. If we have this expression, we can build this set
completely. Let describe the set of even numbers in this manner. We know that this set is made
by this numbers: {0, 2, 4, 6, 8, 10, ...}. With a glance we understand that all of this numbers are
also a natural number, in other words if we add some extra conditions to characteristic property of
natural numbers, we can build a new expression which describe this set. So we can describe with
this expression: {n | n is a member of natural numbers and the reminder of n on 2 is zero}. Now we
can create a filter which get the characteristic property of a set and filter some desired elements to
return elements of our set. For example if we have a natural number filter, both of natural numbers
and even numbers can pass this filter, but if we have a even number filter, then some elements
like 3 and 137871 can't pass the filter.
Definition of interface in Go is like defining the characteristic property and mechanism of using
interface as an argument of a function is like a filter which detect the element is a member of our
desired set or not. Lets describe this aspect with code:
https://riptutorial.com/ 135
www.dbooks.org
IsEvenNumber() bool // the implementation filter 3 from 2
}
The characteristic property of Number is all structures that have IsNumber method, for NaturalNumber
is all ones that have IsNumber and IsNaturalNumber methods and finally for EvenNumber is all types
which have IsNumber, IsNaturalNumber and IsEvenNumber methods. Thanks to this interpretation of
interface, easily we can understand that since interface{} doesn't have any characteristic
property, accept all types (because it doesn't have any filter for distinguishing between values).
https://riptutorial.com/ 136
Chapter 34: Iota
Introduction
Iota provides a way of declaring numeric constants from a starting value that grows monotonically.
Iota can be used to declare bitmasks which are often used in system and network programming
and other lists of constants with related values.
Remarks
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.
Examples
Simple use of iota
const (
a = iota // a = 0
b = iota // b = 1
c = iota // c = 2
)
To create a list of constants in a shortened way - assign iota value to the first element:
const (
a = iota // a = 0
b // b = 1
c // c = 2
)
iota can be used in expressions, so it can also be used to assign values other than simple
incrementing integers starting from zero. To create constants for SI units, use this example from
Effective Go:
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota)
MB
https://riptutorial.com/ 137
www.dbooks.org
GB
TB
PB
EB
ZB
YB
)
Skipping values
The value of iota is still incremented for every entry in a constant list even if iota is not used:
it will also be incremented even if no constant is created at all, meaning the empty identifier can be
used to skip values entirely:
const (
a = iota // a = 0
_ // iota is incremented
b // b = 2
)
The first code block was taken from the Go Spec (CC-BY 3.0).
Because iota is incremented after each ConstSpec, values within the same expression list will have
the same value for iota:
const (
bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0
bit1, mask1 // bit1 == 2, mask1 == 1
_, _ // skips iota == 2
bit3, mask3 // bit3 == 8, mask3 == 7
)
Iota can be very useful when creating a bitmask. For instance, to represent the state of a network
connection which may be secure, authenticated, and/or ready, we might create a bitmask like the
following:
const (
https://riptutorial.com/ 138
Secure = 1 << iota // 0b001
Authn // 0b010
Ready // 0b100
)
ConnState := Secure|Authn // 0b011: Connection is secure and authenticated, but not yet Ready
This is an enumeration for const creation. Go compiler starts iota from 0 and increments by one for
each following constant. The value is determined at compile time rather than run time. Because of
this we can't apply iota to expressions which are evaluated at run time.
package main
import "fmt"
const (
Low = 5 * iota
Medium
High
)
func main() {
// Use our iota constants.
fmt.Println(Low)
fmt.Println(Medium)
fmt.Println(High)
}
Try it in Go Playground
https://riptutorial.com/ 139
www.dbooks.org
Chapter 35: JSON
Syntax
• func Marshal(v interface{}) ([]byte, error)
• func Unmarshal(data []byte, v interface{}) error
Remarks
The package "encoding/json" Package json implements encoding and decoding of JSON objects
in Go.
boolean bool
string string
null nil
Examples
Basic JSON Encoding
The parameter is the value to encode. The returned values are an array of bytes representing the
JSON-encoded input (on success), and an error (on failure).
https://riptutorial.com/ 140
Playground
data, _ = json.Marshal(1)
fmt.Println(string(data))
// 1
data, _ = json.Marshal("1")
fmt.Println(string(data))
// "1"
data, _ = json.Marshal(true)
fmt.Println(string(data))
// true
Playground
Encoding simple variables is helpful to understand how the JSON encoding works in Go.
However, in the real world, you'll likely encode more complex data stored in structs.
json.Unmarshal from the package "encoding/json" decodes a JSON value into the value pointed by
the given variable.
The parameters are the value to decode in []bytes and a variable to use as a storage for the de-
serialized value. The returned value is an error (on failure).
encodedValue := []byte(`{"London":18,"Rome":30}`)
fmt.Println(data)
map[London:18 Rome:30]
Playground
Notice how in the example above we knew in advance both the type of the key and the value. But
https://riptutorial.com/ 141
www.dbooks.org
this is not always the case. In fact, in most cases the JSON contains mixed value types.
encodedValue := []byte(`{"city":"Rome","temperature":30}`)
Playground
In the last example above we used a generic map to store the decoded value. We must use a
map[string]interface{} because we know that the keys are strings, but we don't know the type of
their values in advance.
This is a very simple approach, but it's also extremely limited. In the real world, you would
generally decode a JSON into a custom-defined struct type.
Let's assume we have a file called data.json with the following content:
[
{
"Name" : "John Doe",
"Standard" : 4
},
{
"Name" : "Peter Parker",
"Standard" : 11
},
{
"Name" : "Bilbo Baggins",
"Standard" : 150
}
]
The following example reads the file and decodes the content:
package main
import (
"encoding/json"
"fmt"
https://riptutorial.com/ 142
"log"
"os"
)
func main() {
// open the file pointer
studentFile, err := os.Open("data.json")
if err != nil {
log.Fatal(err)
}
defer studentFile.Close()
The file data.json must be in the same directory of the Go executable program. Read Go File I/O
documentation for more information on how to work with files in Go.
The goal with using anonymous structs is to decode only the information we care about without
littering our app with types that are used only in a single function.
jsonBlob := []byte(`
{
"_total": 1,
"_links": {
"self":
"https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=0",
"next":
"https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25"
},
"subscriptions": [
{
https://riptutorial.com/ 143
www.dbooks.org
"created_at": "2011-11-23T02:53:17Z",
"_id": "abcdef0000000000000000000000000000000000",
"_links": {
"self": "https://api.twitch.tv/kraken/channels/foo/subscriptions/bar"
},
"user": {
"display_name": "bar",
"_id": 123456,
"name": "bar",
"staff": false,
"created_at": "2011-06-16T18:23:11Z",
"updated_at": "2014-10-23T02:20:51Z",
"logo": null,
"_links": {
"self": "https://api.twitch.tv/kraken/users/bar"
}
}
}
]
}
`)
var js struct {
Total int `json:"_total"`
Links struct {
Next string `json:"next"`
} `json:"_links"`
Subs []struct {
Created string `json:"created_at"`
User struct {
Name string `json:"name"`
ID int `json:"_id"`
} `json:"user"`
} `json:"subscriptions"`
}
Output: {Total:1
Links:{Next:https://api.twitch.tv/kraken/channels/foo/subscriptions?direction=ASC&limit=25&offset=25}
Subs:[{Created:2011-11-23T02:53:17Z User:{Name:bar ID:123456}}]}
Playground
https://riptutorial.com/ 144
}
To export Revenue and Sales, but hide them from encoding/decoding, use json:"-" or rename the
variable to begin with a lowercase letter. Note that this prevents the variable from being visible
outside the package.
To prevent Location from being included in the JSON when it is set to its zero value, add
,omitempty to the json tag.
Example in Playground
As a good developer you have created following struct with both exported and unexported fields:
Now you want to Marshal() this struct into valid JSON for storage in something like etcd. However,
since uuid in not exported, the json.Marshal() skips it. What to do? Use an anonymous struct and
the json.MarshalJSON() interface! Here's an example:
https://riptutorial.com/ 145
www.dbooks.org
}{
Uuid: m.uuid,
Name: m.Name,
})
if err != nil {
return nil, err
}
return j, nil
}
Let's assume we have the following struct that defines a City type:
First of all, we need to use the Go metadata to tell the encoder the correspondence between the
struct fields and the JSON keys.
To keep this example simple, we'll declare an explicit correspondence between the fields and the
keys. However, you can use several variants of the json: metadata as explained in the docs.
IMPORTANT: Only exported fields (fields with capital name) will be serialized/deserialized.
For example, if you name the field temperature it will be ignored even if you set the json metadata.
Encoding
To encode a City struct, use json.Marshal as in the basic example:
// data to encode
city := City{Name: "Rome", Temperature: 30}
fmt.Println(string(bytes))
https://riptutorial.com/ 146
// {"name":"Rome","temp":30}
Playground
Decoding
To decode a City struct, use json.Unmarshal as in the basic example:
// data to decode
bytes := []byte(`{"name":"Rome","temp":30}`)
fmt.Println(city)
// {Rome 30}
Playground
https://riptutorial.com/ 147
www.dbooks.org
Chapter 36: JWT Authorization in Go
Introduction
JSON Web Tokens (JWTs) are a popular method for representing claims securely between two
parties. Understanding how to work with them is important when developing web applications or
application programming interfaces.
Remarks
context.Context and HTTP middleware are outside the scope of this topic, but nonetheless those
curious, wandering souls should check out https://github.com/goware/jwtauth,
https://github.com/auth0/go-jwt-middleware, and https://github.com/dgrijalva/jwt-go.
Examples
Parsing and validating a token using the HMAC signing method
// Parse takes the token string and a function for looking up the key. The latter is
especially
// useful if you use multiple keys for your application. The standard is to use 'kid' in the
// head of the token to identify which key to use, but the parsed token (head and claims) is
provided
// to the callback, providing flexibility.
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
Output:
bar 1.4444784e+09
https://riptutorial.com/ 148
(From the documentation, courtesy of Dave Grijalva.)
The StandardClaim is embedded in the custom type to allow for easy encoding, parsing and
validation of standard claims.
tokenString :=
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.HE7fK0xOQwFEr
Output:
bar 15000
Creating, signing, and encoding a JWT token using the HMAC signing method
// Create a new token object, specifying signing method and the claims
// you would like it to contain.
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
// Sign and get the complete encoded token as a string using the secret
tokenString, err := token.SignedString(hmacSampleSecret)
fmt.Println(tokenString, err)
Output:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.u1riaD1rW97opCoAuRCTy4w58
Zk-bh7vLiRIsrpU <nil>
https://riptutorial.com/ 149
www.dbooks.org
(From the documentation, courtesy of Dave Grijalva.)
The StandardClaims type is designed to be embedded into your custom types to provide standard
validation features. You can use it alone, but there's no way to retrieve other fields after parsing.
See the custom claims example for intended usage.
mySigningKey := []byte("AllYourBase")
Output:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDAwLCJpc3MiOiJ0ZXN0In0.QsODzZu3lUZMVdhbO76u3Jv02iYCvE
<nil>
if token.Valid {
fmt.Println("You look nice today")
} else if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
fmt.Println("That's not even a token")
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
// Token is either expired or not active yet
fmt.Println("Timing is everything")
} else {
fmt.Println("Couldn't handle this token:", err)
}
} else {
fmt.Println("Couldn't handle this token:", err)
}
Output:
https://riptutorial.com/ 150
Timing is everything
const (
// JWTTokenContextKey holds the key used to store a JWT Token in the
// context.
JWTTokenContextKey contextKey = "JWTToken"
// JWTClaimsContextKey holds the key used to store the JWT Claims in the
// context.
JWTClaimsContextKey contextKey = "JWTClaims"
)
https://riptutorial.com/ 151
www.dbooks.org
Chapter 37: Logging
Examples
Basic Printing
Go has a built-in logging library known as log with a commonly use method Print and its variants.
You can import the library then do some basic printing:
package main
import "log"
func main() {
log.Println("Hello, world!")
// Prints 'Hello, world!' on a single line
Logging to file
It is possible to specify log destination with something that statisfies io.Writer interface. With that
we can log to file:
package main
import (
"log"
"os"
)
func main() {
logfile, err := os.OpenFile("test.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
log.Fatalln(err)
}
defer logfile.Close()
log.SetOutput(logfile)
log.Println("Log entry")
}
Output:
https://riptutorial.com/ 152
$ cat test.log
2016/07/26 07:29:05 Log entry
Logging to syslog
package main
import (
"log"
"log/syslog"
)
func main() {
syslogger, err := syslog.New(syslog.LOG_INFO, "syslog_example")
if err != nil {
log.Fatalln(err)
}
log.SetOutput(syslogger)
log.Println("Log entry")
}
https://riptutorial.com/ 153
www.dbooks.org
Chapter 38: Loops
Introduction
As one of the most basic functions in programming, loops are an important piece to nearly every
programming language. Loops enable developers to set certain portions of their code to repeat
through a number of loops which are referred to as iterations. This topic covers using multiple
types of loops and applications of loops in Go.
Examples
Basic Loop
for is the only loop statement in go, so a basic loop implementation could look like this:
// would print:
// iteration 0
// iteration 1
// iteration 2
Breaking out of the loop and continuing to the next iteration is also supported in Go, like in many
other languages:
// would print:
// iteration 3
// iteration 4
// iteration 5
The break and continue statements additionally accept an optional label, used to identify outer
loops to target with the statement:
https://riptutorial.com/ 154
OuterLoop:
for {
for {
if allDone() {
break OuterLoop
}
if innerDone() {
continue OuterLoop
}
// do something
}
}
Conditional loop
The for keyword is also used for conditional loops, traditionally while loops in other programming
languages.
package main
import (
"fmt"
)
func main() {
i := 0
for i < 3 { // Will repeat if condition is true
i++
fmt.Println(i)
}
}
play it on playground
Will output:
1
2
3
infinite loop:
for {
// This will run until a return or break.
}
https://riptutorial.com/ 155
www.dbooks.org
Using two variables (or more):
i := 0
for ; i < 10; i++ {
fmt.Print(i, " ")
}
for i := 1; ; i++ {
if i&1 == 1 {
continue
}
if i == 22 {
break
}
fmt.Print(i, " ")
}
When all three initialization, test and increment expressions are removed, the loop
becomes infinite:
i := 0
for {
fmt.Print(i, " ")
i++
if i == 10 {
break
}
}
for i := 0; ; {
fmt.Print(i, " ")
if i == 9 {
break
}
i++
}
https://riptutorial.com/ 156
When just the test expression is used (acts like a typical while loop):
i := 0
for i < 10 {
fmt.Print(i, " ")
i++
}
i := 0
for ; ; i++ {
fmt.Print(i, " ")
if i == 9 {
break
}
}
ary := [5]int{0, 1, 2, 3, 4}
for index, value := range ary {
fmt.Println("ary[", index, "] =", value)
}
Iterate over a range using key and value for map (may not be in order):
Iterate over a range using just key for map (may be not in order):
https://riptutorial.com/ 157
www.dbooks.org
for key := range mp {
fmt.Print(key, " ") //One Two Three
}
Iterate over a range using just key for map (may be not in order):
Iterate over a range using just value for map (may be not in order):
for i := range ch {
fmt.Print(i, " ")
}
as you see utf8str has 6 runes (Unicode code points) and 7 bytes.
Timed loop
package main
import(
"fmt"
"time"
)
func main() {
for _ = range time.Tick(time.Second * 3) {
fmt.Println("Ticking every 3 seconds")
https://riptutorial.com/ 158
}
}
https://riptutorial.com/ 159
www.dbooks.org
Chapter 39: Maps
Introduction
Maps are data types used for storing unordered key-value pairs, so that looking up the value
associated to a given key is very efficient. Keys are unique. The underlying data structure grows
as needed to accommodate new elements, so the programmer does not need to worry about
memory management. They are similar to what other languages call hash tables, dictionaries, or
associative arrays.
Syntax
• var mapName map[KeyType]ValueType // declare a Map
• var mapName = map[KeyType]ValueType{} // declare and assign an empty Map
• var mapName = map[KeyType]ValueType{key1: val1, key2: val2} // declare and assign a
Map
• mapName := make(map[KeyType]ValueType) // declare and initialize default size map
• mapName := make(map[KeyType]ValueType, length) // declare and initialize length size
map
• mapName := map[KeyType]ValueType{} // auto-declare and assign an empty Map with :=
• mapName := map[KeyType]ValueType{key1: value1, key2: value2} // auto-declare and
assign a Map with :=
• value := mapName[key] // Get value by key
• value, hasKey := mapName[key] // Get value by key, 'hasKey' is 'true' if key exists in map
• mapName[key] = value // Set value by key
Remarks
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).
Examples
Declaring and initializing a map
You define a map using the keyword map, followed by the types of its keys and its values:
Maps are reference types, and once defined they have a zero value of nil. Writes to nil maps will
https://riptutorial.com/ 160
panic and reads will always return the zero value.
m := make(map[string]int)
With the two-parameter form of make, it's possible to specify an initial entry capacity for the map,
overriding the default capacity:
m := make(map[string]int, 30)
Alternatively, you can declare a map, initializing it to its zero value, and then assign a literal value
to it later, which helps if you marshal the struct into json thereby producing an empty map on
return.
m := make(map[string]int, 0)
You can also make a map and set its initial value with curly brackets ({}).
fmt.Println(m["Foo"]) // outputs 20
All the following statements result in the variable being bound to the same value.
// Declare via short variable declaration and initialize with a literal value.
m := map[string]int{}
We can also use a map literal to create a new map with some initial key/value pairs.
The key type can be any comparable type; notably, this excludes functions, maps, and slices. The
value type can be any type, including custom types or interface{}.
https://riptutorial.com/ 161
www.dbooks.org
// Declare and initialize via literal value.
var m = map[string]Person{}
// Declare via short variable declaration and initialize with a literal value.
m := map[string]Person{}
Creating a map
One can declare and initialize a map in a single statement using a composite literal.
https://riptutorial.com/ 162
You can create an empty map simply by not entering any value within the brackets {}.
mapIntInt := map[int]int{}
mapIntString := map[int]string{}
mapStringInt := map[string]int{}
mapStringString := map[string]string{}
mapStringPerson := map[string]Person{}
You can create and use a map directly, without the need to assign it to a variable. However, you
will have to specify both the declaration and the content.
// equivalent to
data := map[string]string{
"FirstName": "John",
"LastName": "Doe",
"Age": "30"}
fmt.Println(data)
var m map[string]string
fmt.Println(m == nil) // true
fmt.Println(len(m) ==0) // true
A nil map has no keys nor can keys be added. A nil map behaves like an empty map if read from
but causes a runtime panic if written to.
var m map[string]string
// reading
m["foo"] == "" // true. Remember "" is the zero value for a string
_, ok = m["foo"] // ok == false
// writing
m["foo"] = "bar" // panic: assignment to entry in nil map
You should not try to read from or write to a zero value map. Instead, initialize the map (with make
or assignment) before using it.
var m map[string]string
m = make(map[string]string) // OR m = map[string]string{}
m["foo"] = "bar"
https://riptutorial.com/ 163
www.dbooks.org
import fmt
people := map[string]int{
"john": 30,
"jane": 29,
"mark": 11,
}
Note that when iterating over a map with a range loop, the iteration order is not specified and is
not guaranteed to be the same from one iteration to the next.
You can also discard either the keys or the values of the map, if you are looking to just grab keys
or just grab values.
people := map[string]int{
"john": 30,
"jane": 29,
"mark": 11,
}
If you are just looking for the keys, since they are the first value, you can simply drop the
underscore:
Note that when iterating over a map with a range loop, the iteration order is not specified and is
not guaranteed to be the same from one iteration to the next.
The delete built-in function removes the element with the specified key from a map.
delete(people, "john")
fmt.Println(people) // map[jane:29]
https://riptutorial.com/ 164
people := map[string]int{"john": 30, "jane": 29}
fmt.Println(people) // map[john:30 jane:29]
delete(people, "notfound")
fmt.Println(people) // map[john:30 jane:29]
m := map[string]int{}
len(m) // 0
m["foo"] = 1
len(m) // 1
var m map[string]int
len(m) // 0
Maps in go are not safe for concurrency. You must take a lock to read and write on them if you will
be accessing them concurrently. Usually the best option is to use sync.RWMutex because you can
have read and write locks. However, a sync.Mutex could also be used.
// Get is a wrapper for getting the value from the underlying map
func (r RWMap) Get(key string) int {
r.RLock()
defer r.RUnlock()
return r.m[key]
}
// Set is a wrapper for setting the value of a key in the underlying map
func (r RWMap) Set(key string, val int) {
r.Lock()
defer r.Unlock()
r.m[key] = val
}
https://riptutorial.com/ 165
www.dbooks.org
}
func main() {
// Init
counter := RWMap{m: make(map[string]int)}
The trade-off of the wrapper functions is between the public access of the underlying map and
using the appropriate locks correctly.
m := make(map[string][]int)
Accessing a non-existent key will return a nil slice as a value. Since nil slices act like zero length
slices when used with append or other built-in functions you do not normally need to check to see if
a key exists:
Deleting a key from map sets the key back to a nil slice:
delete(m, "key1")
// m["key1"] == nil
To get a value from the map, you just have to do something like:00
https://riptutorial.com/ 166
values...)
To differentiate between empty values and non-existent keys, you can use the second returned
value of the map access (using like value, hasKey := map["key"]).
people := map[string]int{
"john": 30,
"jane": 29,
"mark": 11,
}
Note that when iterating over a map with a range loop, the iteration order is not specified and is
not guaranteed to be the same from one iteration to the next.
Copy a Map
Like slices, maps hold references to an underlying data structure. So by assigning its value to
another variable, only the reference will be passed. To copy the map, it is necessary to create
another map and copy each value:
https://riptutorial.com/ 167
www.dbooks.org
// Create the target map
targetMap := make(map[string]int)
Some languages have a native structure for sets. To make a set in Go, it's best practice to use a
map from the value type of the set to an empty struct (map[Type]struct{}).
// To delete a value:
delete(greetings, "hi")
// To add a value:
greetings["hey"] = struct{}{}
https://riptutorial.com/ 168
Chapter 40: Memory pooling
Introduction
sync.Pool stores a cache of allocated but unused items for future use, avoiding memory churn for
frequently changed collections, and allowing efficient, thread-safe re-use of memory. It is useful to
manage a group of temporary items shared between concurrent clients of a package, for example
a list of database connections or a list of output buffers.
Examples
sync.Pool
package main
import (
"bytes"
"fmt"
"sync"
)
func main() {
// When getting from a Pool, you need to cast
s := pool.Get().(*bytes.Buffer)
// We write to the object
s.Write([]byte("dirty"))
// Then put it back
pool.Put(s)
https://riptutorial.com/ 169
www.dbooks.org
pool.Put(s)
https://riptutorial.com/ 170
Chapter 41: Methods
Syntax
• func (t T) exampleOne(i int) (n int) { return i } // this function will receive copy of struct
• func (t *T) exampleTwo(i int) (n int) { return i } // this method will receive pointer to struct and
will be able to modify it
Examples
Basic methods
package main
import (
"fmt"
)
func main() {
Bob := new(Employee)
Bob.Rank = 1
fmt.Println("Bobs rank now is: ", Bob.Rank)
fmt.Println("Lets promote Bob!")
Bob.Promote()
Output:
https://riptutorial.com/ 171
www.dbooks.org
Chaining methods
With methods in golang you can do method "chaining" passing pointer to method and returning
pointer to the same struct like this:
package main
import (
"fmt"
)
func main() {
worker := new(Employee)
worker.Rank = 1
worker.SetName("Bob").Promote()
Output:
Though Go supports ++ and -- operators and the behaviour is found to be almost similar to c/c++,
variables with such operators cannot be passed as argument to function.
package main
import (
"fmt"
https://riptutorial.com/ 172
)
https://riptutorial.com/ 173
www.dbooks.org
Chapter 42: mgo
Introduction
mgo (pronounced as mango) is a MongoDB driver for the Go language that implements a rich and
well tested selection of features under a very simple API following standard Go idioms.
Remarks
API Documentation
[https://gopkg.in/mgo.v2][1]
Examples
Example
package main
import (
"fmt"
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func main() {
session, err := mgo.Dial("server1.example.com,server2.example.com")
if err != nil {
panic(err)
}
defer session.Close()
c := session.DB("test").C("people")
err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
&Person{"Cla", "+55 53 8402 8510"})
if err != nil {
log.Fatal(err)
}
result := Person{}
err = c.Find(bson.M{"name": "Ale"}).One(&result)
if err != nil {
log.Fatal(err)
https://riptutorial.com/ 174
}
fmt.Println("Phone:", result.Phone)
}
https://riptutorial.com/ 175
www.dbooks.org
Chapter 43: Middleware
Introduction
In Go Middleware can be used to execute code before and after handler function. It uses the
power of Single Function Interfaces. Can be introduced at any time without affecting the other
middleware. For Ex: Authentication logging can be added in later stages of development without
disturbing the existing code.
Remarks
The Signature of middleware should be (http.ResponseWriter, *http.Request) i.e. of
http.handlerFunc type.
Examples
Normal Handler Function
func main() {
http.HandleFunc("/login", loginHandler)
http.ListenAndServe(":8080", nil)
}
func main() {
http.HandleFunc("/login", Logger(loginHandler))
http.ListenAndServe(":8080", nil)
}
https://riptutorial.com/ 176
CORS Middleware
func main() {
http.HandleFunc("/login", Logger(CORS(loginHandler)))
http.ListenAndServe(":8080", nil)
}
Auth Middleware
https://riptutorial.com/ 177
www.dbooks.org
Chapter 44: Mutex
Examples
Mutex Locking
Mutex locking in Go allows you to ensure that only one goroutine at a time has a lock:
import "sync"
func mutexTest() {
lock := sync.Mutex{}
go func(m *sync.Mutex) {
m.Lock()
defer m.Unlock() // Automatically unlock when this function returns
// Do some things
}(&lock)
lock.Lock()
// Do some other things
lock.Unlock()
}
Using a Mutex allows you to avoid race conditions, concurrent modifications, and other issues
associated with multiple concurrent routines operating on the same resources. Note that
Mutex.Unlock() can be executed by any routine, not just the routine that got the lock. Also note that
the call to Mutex.Lock() will not fail if another routine holds the lock; it will block until the lock is
released.
Tip: Whenever you're passing a Mutex variable to a function, always pass it as a pointer.
Otherwise a copy is made of your variable, which defeats the purpose of the Mutex. If you're using
an older Go version (< 1.7), the compiler will not warn you about this mistake!
https://riptutorial.com/ 178
Chapter 45: Object Oriented Programming
Remarks
Interface can't be implemented with pointer receivers because *User is not User
Examples
Structs
Go supports user defined types in the form of structs and type aliases. structs are composite
types, the component pieces of data that constitute the struct type are called fields. a field has a
type and a name which must be unqiue.
package main
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user := new(User)
user.ID = 1
user.FullName = "Zelalem Mekonen"
user.Email = "[email protected]"
Embedded structs
because a struct is also a data type, it can be used as an anonymous field, the outer struct can
directly access the fields of the embedded struct even if the struct came from a diffrent package.
this behaviour provides a way to derive some or all of your implementation from another type or a
https://riptutorial.com/ 179
www.dbooks.org
set of types.
package main
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
fmt.Println(user.Username) // zola
fmt.Println(user.Password) // supersecretpassword
}
Methods
In Go a method is
the receiver can be anything, not only structs but even a function, alias types for built in types
such as int, string, bool can have a method, an exception to this rule is that interfaces(discussed
later) cannot have methods, since an interface is an abstract definition and a method is an
implementation, trying it generate a compile error.
combining structs and methods you can get a close eqivalent of a class in Object Oriented
programming.
package main
https://riptutorial.com/ 180
type Admin struct {
Username, Password string
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
admin,
}
the receiver of a method is usually a pointer for performance reason because we wouldn't make a
copy of the instance, as it would be the case in value receiver, this is especially true if the receiver
type is a struct. anoter reason to make the receiver type a pointer would be so we could modify the
data the receiver points to.
a value receiver is used to avoid modification of the data the receiver contains, a vaule receiver
may cause a performance hit if the receiver is a large struct.
package main
https://riptutorial.com/ 181
www.dbooks.org
// ChangeMail will modify the users email because the receiver type is a ponter
func (user *User) ChangeEmail(email string) {
user.Email = email;
}
func main() {
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
user.ChangeEmail("[email protected]")
fmt.Println(user.Email) // [email protected]
}
Interfaces provide a way to specify the behaviour of an object, if something can do this then it can
be used here. an interface defines a set of methods, but these methods do not contain code as
they are abstract or the implemntation is left to the user of the interface. unlike most Object
Oriented languages interfaces can contain variables in Go.
package main
https://riptutorial.com/ 182
}
func main() {
admin := Admin{
"zola",
"supersecretpassword",
}
user := User{
1,
"Zelalem Mekonen",
"[email protected]",
}
RunnerExample(admin)
RunnerExample(user)
https://riptutorial.com/ 183
www.dbooks.org
Chapter 46: OS Signals
Syntax
• func Notify(c chan<- os.Signal, sig ...os.Signal)
Parameters
Parameter Details
c chan<- Receiving channel specifically of type os.Signal; easily created with sigChan
os.Signal := make(chan os.Signal)
sig List of os.Signal types to catch and send down this channel. See
...os.Signal https://golang.org/pkg/syscall/#pkg-constants for more options.
Examples
Assigning signals to a channel
Often times you will have reason to catch when your program is being told to stop by the OS and
take some actions to preserve the state, or clean up your application. To accomplish this you can
use the os/signal package from the standard library. Below is a simple example of assigning all
signals from the system to a channel, and then how to react to those signals.
package main
import (
"fmt"
"os"
"os/signal"
)
func main() {
// create a channel for os.Signal
sigChan := make(chan os.Signal)
https://riptutorial.com/ 184
When you run the above script it will create a channel, and then block until that channel receives a
signal.
$ go run signals.go
^CReceived signal from OS: interrupt
The ^C above is the keyboard command CTRL+C which sends the SIGINT signal.
https://riptutorial.com/ 185
www.dbooks.org
Chapter 47: Packages
Examples
Package initalization
Package can have init methods which are run only once before main.
package usefull
func init() {
// init code
}
If you just want to run the package initialization without referencing anything from it use the
following import expression.
import _ "usefull"
A common way to download Go dependencies is by using the go get <package> command, which
will save the package into the global/shared $GOPATH/src directory. This means that a single version
of each package will be linked into each project that includes it as a dependency. This also means
that when a new developers deploys your project, they will go get the latest version of each
dependency.
However you can keep the build environment consistent, by attaching all the dependencies of a
project into the vendor/ directory. Keeping vendored dependencies committed along with your
project's repository allows you to do per-project dependency versioning, and provide a consistent
environment for your build.
$GOPATH/src/
├── github.com/username/project/
| ├── main.go
| ├── vendor/
| | ├── github.com/pkg/errors
| | ├── github.com/gorilla/mux
It is perfectly fine to use a package name other than the folder name. If we do so, we still have to
import the package based on the directory structure, but after the import we have to refer to it by
the name we used in the package clause.
https://riptutorial.com/ 186
For example, if you have a folder $GOPATH/src/mypck, and in it we have a file a.go:
package apple
const Pi = 3.14
package main
import (
"mypck"
"fmt"
)
func main() {
fmt.Println(apple.Pi)
}
Even though this works, you should have a good reason to deviate package name from the folder
name (or it may become source of misunderstanding and confusion).
Which allows unicode letters to be used in identifiers, e.g. αβ is a valid identifier in Go. Folder and
file names are not handled by Go but by the Operating System, and different file systems have
different restrictions. There are actually many file systems which would not allow all valid Go
identifiers as folder names, so you would not be able to name your packages what otherwise the
language spec would allow.
Having the option to use different package names than their containing folders, you have the
option to really name your packages what the language spec allows, regardless of the underlying
operating and file system.
Importing packages
import "path/to/package"
import (
"path/to/package1"
"path/to/package2"
)
https://riptutorial.com/ 187
www.dbooks.org
This will look in the corresponding import paths inside of the $GOPATH for .go files and lets you
access exported names through packagename.AnyExportedName.
You can also access local packages inside of the current folder by prefacing packages with ./. In
a project with a structure like this:
project
├── src
│ ├── package1
│ │ └── file1.go
│ └── package2
│ └── file2.go
└── main.go
You could call this in main.go in order to import the code in file1.go and file2.go:
import (
"./src/package1"
"./src/package2"
)
Since package-names can collide in different libraries you may want to alias one package to a new
name. You can do this by prefixing your import-statement with the name you want to use.
import (
"fmt" //fmt from the standardlibrary
tfmt "some/thirdparty/fmt" //fmt from some other library
)
This allows you to access the former fmt package using fmt.* and the latter fmt package using
tfmt.*.
You can also import the package into the own namespace, so that you can refer to the exported
names without the package. prefix using a single dot as alias:
import (
. "fmt"
)
Above example imports fmt into the global namespace and lets you call, for example, Printf
directly: Playground
If you import a package but don't use any of it's exported names, the Go compiler will print an
error-message. To circumvent this, you can set the alias to the underscore:
import (
_ "fmt"
)
This can be useful if you don't access this package directly but need it's init functions to run.
https://riptutorial.com/ 188
Note:
As the package names are based on the folder structure, any changes in the folder names &
import references (including case sensitivity) will cause a compile time error "case-insensitive
import collision" in Linux & OS-X, which is difficult to trace and fix (the error message is kinda
cryptic for mere mortals as it tries to convey the opposite - that, the comparison failed due to case
sensitivity).
https://riptutorial.com/ 189
www.dbooks.org
Chapter 48: Panic and Recover
Remarks
This article assumes knowledge of Defer Basics
Examples
Panic
A panic halts normal execution flow and exits the current function. Any deferred calls will then be
executed before control is passed to the next higher function on the stack. Each stack's function
will exit and run deferred calls until the panic is handled using a deferred recover(), or until the
panic reaches main() and terminates the program. If this occurs, the argument provided to panic
and a stack trace will be printed to stderr.
package main
import "fmt"
func foo() {
defer fmt.Println("Exiting foo")
panic("bar")
}
func main() {
defer fmt.Println("Exiting main")
foo()
}
Output:
Exiting foo
Exiting main
panic: bar
goroutine 1 [running]:
panic(0x128360, 0x1040a130)
/usr/local/go/src/runtime/panic.go:481 +0x700
main.foo()
/tmp/sandbox550159908/main.go:7 +0x160
main.main()
/tmp/sandbox550159908/main.go:12 +0x120
It is important to note that panic will accept any type as its parameter.
Recover
https://riptutorial.com/ 190
Recover as the name implies, can attempt to recover from a panic. The recover must be attempted
in a deferred statement as normal execution flow has been halted. The recover statement must
appear directly within the deferred function enclosure. Recover statements in functions called by
deferred function calls will not be honored. The recover() call will return the argument provided to
the initial panic, if the program is currently panicking. If the program is not currently panicking,
recover() will return nil.
package main
import "fmt"
func foo() {
panic("bar")
}
func bar() {
defer func() {
if msg := recover(); msg != nil {
fmt.Printf("Recovered with message %s\n", msg)
}
}()
foo()
fmt.Println("Never gets executed")
}
func main() {
fmt.Println("Entering main")
bar()
fmt.Println("Exiting main the normal way")
}
Output:
Entering main
Recovered with message bar
Exiting main the normal way
https://riptutorial.com/ 191
www.dbooks.org
Chapter 49: Parsing Command Line
Arguments And Flags
Examples
Command line arguments
Command line arguments parsing is Go is very similar to other languages. In you code you just
access slice of arguments where first argument will be the name of program itself.
Quick example:
package main
import (
"fmt"
"os"
)
func main() {
progName := os.Args[0]
arguments := os.Args[1:]
fmt.Printf("Here we have program '%s' launched with following flags: ", progName)
fmt.Println("")
}
Each argument is just a string. In os package it looks like: var Args []string
Flags
Go standard library provides package flag that helps with parsing flags passed to program.
Note that flag package doesn't provide usual GNU-style flags. That means that multi-letter flags
must be started with single hyphen like this: -exampleflag , not this: --exampleflag. GNU-style flags
can be done with some 3-rd party package.
package main
https://riptutorial.com/ 192
import (
"flag"
"fmt"
)
func main() {
// if you need to store value in variable, not pointer, than you can
// do it like:
var intFlag int
flag.IntVar(&intFlag, "int.flag", 1, "usage of intFlag")
$ ./flags -h
Usage of ./flags:
-int.flag int
usage of intFlag (default 1)
-string.flag string
here comes usage (default "default value")
$ ./flags
Value of stringFlag is: default value
Value of intFlag is: 1
https://riptutorial.com/ 193
www.dbooks.org
Chapter 50: Parsing CSV files
Syntax
• csvReader := csv.NewReader(r)
• data, err := csvReader.Read()
Examples
Simple CSV parsing
#id,title,text
1,hello world,"This is a ""blog""."
2,second time,"My
second
entry."
And produce:
Playground: https://play.golang.org/p/d2E6-CGGIe.
https://riptutorial.com/ 194
Chapter 51: Plugin
Introduction
Go provides a plugin mechanism that can be used to dynamically link other Go code at runtime.
Examples
Defining and using a plugin
package main
import "fmt"
var V int
go build -buildmode=plugin
p, err := plugin.Open("plugin_name.so")
if err != nil {
panic(err)
}
v, err := p.Lookup("V")
if err != nil {
panic(err)
}
f, err := p.Lookup("F")
if err != nil {
panic(err)
}
*v.(*int) = 7
f.(func())() // prints "Hello, number 7"
https://riptutorial.com/ 195
www.dbooks.org
Chapter 52: Pointers
Syntax
• pointer := &variable // get pointer from variable
• variable := *pointer // get variable from pointer
• *pointer = value // set value from variable through the pointer
• pointer := new(Struct) // get pointer of new struct
Examples
Basic Pointers
Go supports pointers, allowing you to pass references to values and records within your program.
package main
import "fmt"
func main() {
i := 1
fmt.Println("initial:", i) // initial: 1
zeroval(i)
fmt.Println("zeroval:", i) // zeroval: 1
// `i` is still equal to 1 because `zeroval` edited
// a "copy" of `i`, not the original.
https://riptutorial.com/ 196
zeroptr(&i)
fmt.Println("zeroptr:", i) // zeroptr: 0
Pointer Methods
Pointer methods can be called even if the variable is itself not a pointer.
package main
import "fmt"
func main() {
var f Foo
// As you can see, calling `(&f).Increment` directly does the same thing.
f = Foo{}
fmt.Printf("f.Bar is %d\n", f.Bar)
(&f).Increment()
fmt.Printf("f.Bar is %d\n", f.Bar)
}
Play it
https://riptutorial.com/ 197
www.dbooks.org
Value Methods
Similarly to pointer methods, value methods can be called even if the variable is itself not a value.
package main
import "fmt"
func main() {
var p *Foo
// As you can see, calling `(*p).Increment` directly does the same thing.
p = &Foo{}
fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
(*p).Increment()
fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
}
Play it
To learn more about pointer and value methods, visit the Go Spec section on Method Values, or
see the Effective Go section about Pointers v. Values.
Note 1: The parenthesis (()) around *p and &f before selectors like .Bar are there for grouping
purposes, and must be kept.
Note 2: Although pointers can be converted to values (and vice-versa) when they are the receivers
for a method, they are not automattically converted to eachother when they are arguments inside
of a function.
https://riptutorial.com/ 198
Dereferencing Pointers
package main
import (
"fmt"
)
func main() {
c := new(Person) // returns pointer
c.Name = "Catherine"
fmt.Println(c.Name) // prints: Catherine
d := c
d.Name = "Daniel"
fmt.Println(c.Name) // prints: Daniel
// Adding an Asterix before a pointer dereferences the pointer
i := *d
i.Name = "Ines"
fmt.Println(c.Name) // prints: Daniel
fmt.Println(d.Name) // prints: Daniel
fmt.Println(i.Name) // prints: Ines
}
Slices are pointers to arrays, with the length of the segment, and its capacity. They behave as
pointers, and assigning their value to another slice, will assign the memory address. To copy a
slice value to another, use the built-in copy function: func copy(dst, src []Type) int (returns the
amount of items copied).
package main
import (
"fmt"
)
func main() {
x := []byte{'a', 'b', 'c'}
fmt.Printf("%s", x) // prints: abc
y := x
y[0], y[1], y[2] = 'x', 'y', 'z'
fmt.Printf("%s", x) // prints: xyz
z := make([]byte, len(x))
// To copy the value to another slice, but
// but not the memory address use copy:
_ = copy(z, x) // returns count of items copied
fmt.Printf("%s", z) // prints: xyz
z[0], z[1], z[2] = 'a', 'b', 'c'
fmt.Printf("%s", x) // prints: xyz
fmt.Printf("%s", z) // prints: abc
}
https://riptutorial.com/ 199
www.dbooks.org
Simple Pointers
func main() {
x := int(1)
y := int(2)
// variable addresses
swap(&x, &y)
fmt.Println(x, y)
}
https://riptutorial.com/ 200
Chapter 53: Profiling using go tool pprof
Remarks
For more in profiling go programs visit the go blog.
Examples
Basic cpu and memory profiling
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
...
if *memprofile != "" {
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
}
after that build the go program if added in main go build main.go. Run main program with flags
defined in code main.exe -cpuprofile cpu.prof -memprof mem.prof. If the profiling is done for test
cases run the tests with same flags go test -cpuprofile cpu.prof -memprofile mem.prof
func main() {
flag.Parse()
if *memprofile != "" {
https://riptutorial.com/ 201
www.dbooks.org
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)
}
runtime.GC() // get up-to-date statistics
if err := pprof.WriteHeapProfile(f); err != nil {
log.Fatal("could not write memory profile: ", err)
}
f.Close()
}
}
go build main.go
main.exe -memprofile mem.prof
go tool pprof main.exe mem.prof
// Controls the fraction of goroutine blocking events that are reported in the blocking
profile
// Rate = 1 includes every blocking event in the profile
// Rate <= 0 turns off profiling
runtime.SetBlockProfileRate(rate)
For a non-main packages as well as main, instead of adding flags inside the code, write
benchmarks in the test package , for example:
And the benchmarks will be run and create a prof file with filename cpu.prof (in the above
example).
once a prof file has been generated, one can access the prof file using go tools:
https://riptutorial.com/ 202
This will enter into a command line interface for exploring the profile
(pprof) top
(pprof) peek
(pprof) web
https://riptutorial.com/ 203
www.dbooks.org
Chapter 54: Protobuf in Go
Introduction
Protobuf or Protocol Buffer encodes and decodes data so that different applications or modules
written in unlike languages can exchange the large number of messages quickly and reliably
without overloading the communication channel. With protobuf, the performance is directly
proportional to the number of message you tend to send. It compress the message to send in a
serialized binary format by providing your the tools to encode the message at source and decode
it at the destination.
Remarks
There are two steps of using protobuf.
gRPC Support
If a proto file specifies RPC services, protoc-gen-go can be instructed to generate code compatible
with gRPC (http://www.grpc.io/). To do this, pass the plugins parameter to protoc-gen-go; the
usual way is to insert it into the --go_out argument to protoc:
Examples
Using Protobuf with Go
The message you want to serialize and send that you can include into a file test.proto, containing
package example;
message Test {
required string label = 1;
optional int32 type = 2 [default=77];
repeated int64 reps = 3;
optional group OptionalGroup = 4 {
required string RequiredField = 5;
}
}
To compile the protocol buffer definition, run protoc with the --go_out parameter set to the
directory you want to output the Go code to.
https://riptutorial.com/ 204
protoc --go_out=. *.proto
To create and play with a Test object from the example package,
package main
import (
"log"
"github.com/golang/protobuf/proto"
"path/to/example"
)
func main() {
test := &example.Test {
Label: proto.String("hello"),
Type: proto.Int32(17),
Reps: []int64{1, 2, 3},
Optionalgroup: &example.Test_OptionalGroup {
RequiredField: proto.String("good bye"),
},
}
data, err := proto.Marshal(test)
if err != nil {
log.Fatal("marshaling error: ", err)
}
newTest := &example.Test{}
err = proto.Unmarshal(data, newTest)
if err != nil {
log.Fatal("unmarshaling error: ", err)
}
// Now test and newTest contain the same data.
if test.GetLabel() != newTest.GetLabel() {
log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
}
// etc.
}
To pass extra parameters to the plugin, use a comma-separated parameter list separated from the
output directory by a colon:
https://riptutorial.com/ 205
www.dbooks.org
Chapter 55: Readers
Examples
Using bytes.Reader to read from a string
One implementation of the io.Reader interface can be found in the bytes package. It allows a byte
slice to be used as the source for a Reader. In this example the byte slice is taken from a string,
but is more likely to have been read from a file or network connection.
reader := bytes.NewReader(message)
bs := make([]byte, 5)
n, err := reader.Read(bs)
if err != nil {
log.Fatal(err)
}
Go Playground
https://riptutorial.com/ 206
Chapter 56: Reflection
Remarks
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)
Examples
Basic reflect.Value Usage
import "reflect"
value := reflect.ValueOf(4)
// Type gets the reflect.Type, which contains runtime type information about
// this value
value.Type().Name() // int
x := 4
reflect.ValueOf(&x).Elem().SetInt(5) // works
Structs
import "reflect"
type S struct {
A int
b string
}
s := &S{
A: 5,
b: "example",
}
value.FieldByName("A").Interface() // 5
value.Field(2).Interface() // "example"
https://riptutorial.com/ 207
www.dbooks.org
value.NumMethod() // 0, since String takes a pointer receiver
indirect.NumMethod() // 1
indirect.Method(0).Call([]reflect.Value{}) // "example"
indirect.MethodByName("String").Call([]reflect.Value{}) // "example"
Slices
import "reflect"
s := []int{1, 2, 3}
value := reflect.ValueOf(s)
value.Len() // 3
value.Index(0).Interface() // 1
value.Type().Kind() // reflect.Slice
value.Type().Elem().Name() // int
typ := reflect.SliceOf(reflect.TypeOf("example"))
newS := reflect.MakeSlice(typ, 0, 10) // an empty []string{} with capacity 10
reflect.Value.Elem()
import "reflect"
x := 5
ptr := reflect.ValueOf(&x)
ptr.Type().Name() // *int
ptr.Type().Kind() // reflect.Ptr
ptr.Interface() // [pointer to x]
ptr.Set(4) // panic
package main
import (
https://riptutorial.com/ 208
"fmt"
"reflect"
)
type Data struct {
a int
}
func main() {
s:="hey dude"
fmt.Println(reflect.TypeOf(s))
D := Data{a:5}
fmt.Println(reflect.TypeOf(D))
Output :
string
main.Data
https://riptutorial.com/ 209
www.dbooks.org
Chapter 57: Select and Channels
Introduction
The select keyword provides an easy method to work with channels and perform more advanced
tasks. It is frequently used for a number of purposes: - Handling timeouts. - When there are
multiple channels to read from, the select will randomly read from one channel which has data. -
Providing an easy way to define what happens if no data is available on a channel.
Syntax
• select {}
• select { case true: }
• select { case incomingData := <-someChannel: }
• select { default: }
Examples
Simple Select Working with Channels
In this example we create a goroutine (a function running in a separate thread) that accepts a chan
parameter, and simply loops, sending information into the channel each time.
In the main we have a for loop and a select. The select will block processing until one of the case
statements becomes true. Here we have declared two cases; the first is when information comes
through the channel, and the other is if no other case occurs, which is known as default.
import (
"fmt"
"time"
)
https://riptutorial.com/ 210
// Our main function
func main() {
// Create the channel
chatChannel := make(chan string, 1)
// This for loop keeps things going while the chatter is sleeping
for {
// select statement will block this thread until one of the two conditions below is
met
// because we have a default, we will hit default any time the chatter isn't chatting
select {
// anytime the chatter chats, we'll catch it and output it
case spam, ok := <-chatChannel:
// Print the string from the channel, unless the channel is closed
// and we're out of data, in which case exit.
if ok {
fmt.Println(spam)
} else {
fmt.Println("Channel closed, exiting!")
return
}
default:
// print a line, then sleep for 1 second.
fmt.Println("Nothing happened this second.")
time.Sleep(1 * time.Second)
}
}
}
So here, I have removed the for loops, and made a timeout by adding a second case to the select
that returns after 3 seconds. Because the select just waits until ANY case is true, the second case
fires, and then our script ends, and chatter() never even gets a chance to finish.
import (
"fmt"
"time"
)
https://riptutorial.com/ 211
www.dbooks.org
// Create the channel, it will be taking only strings, no need for a buffer on this
project
chatChannel := make(chan string)
// Clean up our channel when we are done
defer close(chatChannel)
// select statement will block this thread until one of the two conditions below is met
// because we have a default, we will hit default any time the chatter isn't chatting
select {
// anytime the chatter chats, we'll catch it and output it
case spam := <-chatChannel:
fmt.Println(spam)
// if the chatter takes more than 3 seconds to chat, stop waiting
case <-time.After(3 * time.Second):
fmt.Println("Ain't no time for that!")
}
}
https://riptutorial.com/ 212
Chapter 58: Send/receive emails
Syntax
• func PlainAuth(identity, username, password, host string) Auth
• func SendMail(addr string, a Auth, from string, to []string, msg []byte) error
Examples
Sending Email with smtp.SendMail()
Sending email is pretty simple in Go. It helps to understand the RFC 822, which specifies the style
an email need to be in, the code below sends a RFC 822 compliant email.
package main
import (
"fmt"
"net/smtp"
)
func main() {
// user we are authorizing as
from := "[email protected]"
// NOTE: Using the backtick here ` works like a heredoc, which is why all the
// rest of the lines are forced to the beginning of the line, otherwise the
// formatting is wrong for the RFC 822 style
message := `To: "Some User" <[email protected]>
From: "Other User" <[email protected]>
Subject: Testing Email From Go!!
https://riptutorial.com/ 213
www.dbooks.org
The above will send a message like the following:
https://riptutorial.com/ 214
Chapter 59: Slices
Introduction
A slice is a data structure that encapsulates an array so that the programmer can add as many
elements as needed without having to worry about memory management. Slices can be cut into
sub-slices very efficiently, since the resulting slices all point to the same internal array. Go
programmers often take advantage of this to avoid copying arrays, which would typically be done
in many other programming languages.
Syntax
• slice := make([]type, len, cap) // create a new slice
• slice = append(slice, item) // append a item to a slice
• slice = append(slice, items...) // append slice of items to a slice
• len := len(slice) // get the length of a slice
• cap := cap(slice) // get the capacity of a slice
• elNum := copy(dst, slice) // copy a the contents of a slice to an other slice
Examples
Appending to slice
slice1 := []string{"!"}
slice2 := []string{"Hello", "world"}
slice := append(slice1, slice2...)
If you need to remove one or more elements from a slice, or if you need to work with a sub slice of
another existing one; you can use the following method.
Following examples uses slice of int, but that works with all type of slice.
So for that, we need a slice, from witch we will remove some elements:
slice := []int{1, 2, 3, 4, 5, 6}
// > [1 2 3 4 5 6]
https://riptutorial.com/ 215
www.dbooks.org
We need also the indexes of elements to remove:
// keeping elements from start to 'first element to remove' (not keeping first to remove),
// removing elements from 'first element to remove' to 'last element to remove'
// and keeping all others elements to the end of the slice
newSlice1 := append(slice[:first], slice[last+1:]...)
// > [1 2 6]
// same that newSlice3 with hard coded indexes (without use of variables)
newSlice4 := slice[:2 + copy(slice[2:], slice[5:])]
// > [1 2 6]
To remove only one element, just have to put the index of this element as the first AND as the last
index to remove, just like that:
var indexToRemove = 3
newSlice5 := append(slice[:indexToRemove], slice[indexToRemove+1:]...)
// > [1 2 3 5 6]
// hard-coded version:
newSlice5 := append(slice[:3], slice[4:]...)
// > [1 2 3 5 6]
And you can also remove elements from the beginning of the slice:
You can also removing some elements from the end of the slice:
https://riptutorial.com/ 216
// > [1 2]
If the new slice have to contains exactly the same elements than the first one, you can
use the same thing but with last := first-1.
(This can be useful in case of your indexes are previously computed)
Slices have both length and capacity. The length of a slice is the number of elements currently in
the slice, while the capacity is the number of elements the slice can hold before needing to be
reallocated.
When creating a slice using the built-in make() function, you can specify its length, and optionally
its capacity. If the capacity is not explicitly specified, it will be the specified length.
You can check the length of a slice with the built-in len() function:
var n = len(s) // n == 3
You can check the capacity with the built-in cap() function:
var c = cap(s) // c == 5
Elements created by make() are set to the zero value for the element type of the slice:
Run it on play.golang.org
You cannot access elements beyond the length of a slice, even if the index is within capacity:
However, as long as the capacity exceeds the length, you can append new elements without
reallocating:
var t = []int{3, 4}
s = append(s, t) // s is now []int{0, 0, 0, 3, 4}
n = len(s) // n == 5
c = cap(s) // c == 5
https://riptutorial.com/ 217
www.dbooks.org
If you append to a slice which lacks the capacity to accept the new elements, the underlying array
will be reallocated for you with sufficient capacity:
var u = []int{5, 6}
s = append(s, u) // s is now []int{0, 0, 0, 3, 4, 5, 6}
n = len(s) // n == 7
c = cap(s) // c > 5
It is, therefore, generally good practice to allocate sufficient capacity when first creating a slice, if
you know how much space you'll need, to avoid unnecessary reallocations.
If you wish to copy the contents of a slice into an initially empty slice, following steps can be taken
to accomplish it-
3. Now that the destination slice's underlying array is big enough to accomodate all the
elements of the source slice, we can proceed to copy the elements using the builtin copy:
copy(destinationSlice,sourceSlice)
Creating Slices
var a []int
To declare and initialize a slice variable in one line use the []Type{values} syntax.
Another way to initialize a slice is with the make function. It three arguments: the Type of the slice (or
map), the length, and the capacity.
a := make([]int, 0, 5)
https://riptutorial.com/ 218
You can add elements to your new slice using append.
a = append(a, 5)
length := len(a)
Check the capacity of your slice using cap. The capacity is the number of elements currently
allocated to be in memory for the slice. You can always append to a slice at capacity as Go will
automatically create a bigger slice for you.
capacity := cap(a)
You can also use a for loop over slices with range. The first variable is the index in the specified
array, and the second variable is the value for the index.
Go Playground
Filtering a slice
The zero value of slice is nil, which has the length and capacity 0. A nil slice has no underlying
https://riptutorial.com/ 219
www.dbooks.org
array. But there are also non-nil slices of length and capacity 0, like []int{} or make([]int, 5)[5:].
Any type that have nil values can be converted to nil slice:
s = []int(nil)
if len(s) == 0 {
fmt.Ptintf("s is empty.")
}
https://riptutorial.com/ 220
Chapter 60: SQL
Remarks
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.
Examples
Querying
This example is showing how to query a database with database/sql, taking as example a MySql
database.
package main
import (
"log"
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
func main() {
dsn := "mysql_username:CHANGEME@tcp(localhost:3306)/dbname"
for rows.Next() {
var id int
var username string
if err := rows.Scan(&id, &username); err != nil {
log.Fatal(err)
}
fmt.Printf("%d-%s\n", id, username)
}
}
MySQL
https://riptutorial.com/ 221
www.dbooks.org
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
Opening a database
Opening a database is database specific, here there are examples for some databases.
Sqlite 3
file := "path/to/file"
db_, err := sql.Open("sqlite3", file)
if err != nil {
panic(err)
}
MySql
dsn := "mysql_username:CHANGEME@tcp(localhost:3306)/dbname"
db, err := sql.Open("mysql", dsn)
if err != nil {
panic(err)
}
MongoDB: connect & insert & remove & update & query
package main
import (
"fmt"
"time"
log "github.com/Sirupsen/logrus"
mgo "gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
https://riptutorial.com/ 222
pass := mdb.Pass
host := mdb.Host
port := mdb.Port
db := mdb.DB
if host == "" || port == "" || db == "" {
log.Fatal("Host or port or db is nil")
}
url := fmt.Sprintf("mongodb://%s:%s@%s:%s/%s", user, pass, host, port, db)
if user == "" {
url = fmt.Sprintf("mongodb://%s:%s/%s", host, port, db)
}
mongo, err := mgo.DialWithTimeout(url, 3*time.Second)
if err != nil {
log.Errorf("Mongo Conn Error: [%v], Mongo ConnUrl: [%v]",
err, url)
errTextReturn := fmt.Sprintf("Mongo Conn Error: [%v]", err)
return &mgo.Session{}, errors.New(errTextReturn)
}
mongoConn = mongo
return mongoConn, nil
}
https://riptutorial.com/ 223
www.dbooks.org
return result, err
}
https://riptutorial.com/ 224
Chapter 61: String
Introduction
A string is in effect a read-only slice of bytes. In Go a string literal will always contain a valid UTF-8
representation of its content.
Syntax
• variableName := "Hello World" // declare a string
• variableName := `Hello World` // declare a raw literal string
• variableName := "Hello " + "World" // concatenates strings
• substring := "Hello World"[0:4] // get a part of the string
• letter := "Hello World"[6] // get a character of the string
• fmt.Sprintf("%s", "Hello World") // formats a string
Examples
String type
The string type allows you to store text, which is a series of characters. There are multiple ways to
create strings. A literal string is created by writing the text between double quotes.
Because Go strings support UTF-8, the previous example is perfectly valid. Strings hold arbitrary
bytes which does not necessarily mean every string will contain valid UTF-8 but string literals will
always hold valid UTF-8 sequences.
Strings can also be defined using backticks ``. This creates a raw string literal which means
characters won't be escaped.
text1 := "Hello\nWorld"
text2 := `Hello
World`
In the previous example, text1 escapes the \n character which represents a new line while text2
contains the new line character directly. If you compare text1 == text2 the result will be true.
https://riptutorial.com/ 225
www.dbooks.org
However, text2 := `Hello\nWorld` would not escape the \n character which means the string
contains the text Hello\nWorld without a new line. It would be the equivalent of typing text1 :=
"Hello\\nWorld".
Formatting text
Package fmt implements functions to print and format text using format verbs. Verbs are
represented with a percent sign.
General verbs:
Boolean:
Integer:
%b // base 2
%c // the character represented by the corresponding Unicode code point
%d // base 10
%o // base 8
%q // a single-quoted character literal safely escaped with Go syntax.
%x // base 16, with lower-case letters for a-f
%X // base 16, with upper-case letters for A-F
%U // Unicode format: U+1234; same as "U+%04X"
Pointer:
https://riptutorial.com/ 226
%p // base 16 notation, with leading 0x
Using the verbs, you can create strings concatenating multiple types:
The function Sprintf formats the string in the first parameter replacing the verbs with the value of
the values in the next parameters and returns the result. Like Sprintf, the function Printf also
formats but instead of returning the result it prints the string.
strings package
• strings.Contains
• strings.HasPrefix
• strings.HasSuffix
• strings.Join
• strings.Replace
• strings.Split
• strings.ToLower
fmt.Println(strings.ToLower("FOOBAR")) // foobar
• strings.ToUpper
fmt.Println(strings.ToUpper("foobar")) // FOOBAR
https://riptutorial.com/ 227
www.dbooks.org
• strings.TrimSpace
More: https://golang.org/pkg/strings/.
https://riptutorial.com/ 228
Chapter 62: Structs
Introduction
Structs are sets of various variables packed together. The struct itself is only a package containing
variables and making them easily accessible.
Unlike in C, Go's structs can have methods attached to them. It also allows them to implement
interfaces. That makes Go's structs similar to objects, but they are (probably intentionally) missing
some major features known in object oriented languages like inheritance.
Examples
Basic Declaration
Each value is called a field. Fields are usually written one per line, with the field's name
preceeding its type. Consecutive fields of the same type may be combined, as FirstName and
LastName in the above example.
Struct fields whose names begin with an uppercase letter are exported. All other names are
unexported.
Unexported fields can only be accessed by code within the same package. As such, if you are
ever accessing a field from a different package, its name needs to start with an uppercase letter.
package main
import "bank"
func main() {
var x = &bank.Account{
UserID: 1, // this works fine
accessToken: "one", // this does not work, since accessToken is unexported
https://riptutorial.com/ 229
www.dbooks.org
}
}
However, from within the bank package, you can access both UserId and accessToken without
issue.
package bank
Composition provides an alternative to inheritance. A struct may include another type by name in
its declaration:
In the example above, AuthenticatedRequest will contain four public members: Resource, Request,
Username, and Password.
Composite structs can be instantiated and used the same way as normal structs:
func main() {
ar := new(AuthenticatedRequest)
ar.Resource = "example.com/request"
ar.Username = "bob"
ar.Password = "P@ssw0rd"
fmt.Printf("%#v", ar)
}
play it on playground
Embedding
https://riptutorial.com/ 230
In the previous example, Request is an embedded field. Composition can also be achieved by
embedding a different type. This is useful, for example, to decorate a Struct with more
functionality. For example, continuing with the Resource example, we want a function that formats
the content of the Resource field to prefix it with http:// or https://. We have two options: create
the new methods on AuthenticatedRequest or embed it from a different struct:
func main() {
ar := new(AuthenticatedRequest)
ar.Resource = "www.example.com/request"
ar.Username = "bob"
ar.Password = "P@ssw0rd"
println(ar.FormatHTTP(ar.Resource))
println(ar.FormatHTTPS(ar.Resource))
fmt.Printf("%#v", ar)
}
But the downside of it is that you cannot access objects outside of your composition. So
ResourceFormatter cannot access members from AuthenticatedRequest.
play it on playground
Methods
https://riptutorial.com/ 231
www.dbooks.org
func (u *User) SetName(newName string) {
u.name = newName
}
The only difference is the addition of the method receiver. It may be declared either as an instance
of the type or a pointer to an instance of the type. Since SetName() mutates the instance, the
receiver must be a pointer in order to effect a permanent change in the instance.
For example:
package main
import "fmt"
func main() {
var me User
me.SetName("Slim Shady")
fmt.Println("My name is", me.Name())
}
Go Playground
Anonymous struct
data := struct {
Number int
Text string
} {
42,
"Hello world!",
}
Full example:
package main
import (
"fmt"
)
https://riptutorial.com/ 232
func main() {
data := struct {Number int; Text string}{42, "Hello world!"} // anonymous struct
fmt.Printf("%+v\n", data)
}
play it on playground
Tags
Struct fields can have tags associated with them. These tags can be read by the reflect package
to get custom information specified about a field by the developer.
struct Account {
Username string `json:"username"`
DisplayName string `json:"display_name"`
FavoriteColor string `json:"favorite_color,omitempty"`
}
In the above example, the tags are used to change the key names used by the encoding/json
package when marshaling or unmarshaling JSON.
While the tag can be any string value, it's considered best practice to use space separated
key:"value" pairs:
struct StructName {
FieldName int `package1:"customdata,moredata" package2:"info"`
}
The struct tags used with the encoding/xml and encoding/json package are used throughout the
standard libarary.
type T struct {
I int
S string
}
// initialize a struct
t := T{1, "one"}
if u == t { // true
fmt.Println("u and t are equal") // Prints: "u and t are equal"
}
In above case, 't' and 'u' are now separate objects (struct values).
https://riptutorial.com/ 233
www.dbooks.org
Since T does not contain any reference types (slices, map, channels) as its fields, t and u above
can be modified without affecting each other.
type T struct {
I int
S string
xs []int // a slice is a reference type
}
Then a simple copy by assignment would copy the value of slice type field as well to the new
object. This would result in two different objects referring to the same slice object.
// initialize a struct
t := T{I: 1, S: "one", xs: []int{1, 2, 3}}
Since both u and t refer to the same slice through their field xs updating a value in the slice of one
object would reflect the change in the other.
Hence, extra care must be taken to ensure this reference type property does not produce
unintended behavior.
To copy above objects for example, an explicit copy of the slice field could be performed:
Struct Literals
A value of a struct type can be written using a struct literal that specifies values for its fields.
https://riptutorial.com/ 234
type Point struct { X, Y int }
p := Point{1, 2}
The above example specifies every field in the right order. Which is not useful, because
programmers have to remember the exact fields in order. More often, a struct can be initialized by
listing some or all of the field names and their corresponding values.
Omitted fields are set to the zero value for its type.
Empty struct
A struct is a sequence of named elements, called fields, each of which has a name and a type.
Empty struct has no fields, like this anonymous empty struct:
var s struct{}
type T struct{}
The interesting thing about the empty struct is that, its size is zero (try The Go Playground):
fmt.Println(unsafe.Sizeof(s))
This prints 0, so the empty struct itself takes no memory. so it is good option for quit channel, like
(try The Go Playground):
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan struct{})
go func() {
time.Sleep(1 * time.Second)
close(done)
}()
fmt.Println("Wait...")
<-done
fmt.Println("done.")
}
https://riptutorial.com/ 235
www.dbooks.org
Read Structs online: https://riptutorial.com/go/topic/374/structs
https://riptutorial.com/ 236
Chapter 63: Templates
Syntax
• t, err := template.Parse({{.MyName .MyAge}})
Remarks
Golang provides packages like:
1. text/template
2. html/template
Examples
Output values of struct variable to Standard Output using a text template
package main
import (
"log"
"text/template"
"os"
)
func main() {
t,err := template.New("myTemp").Parse(myTempContents)
if err != nil{
log.Fatal(err)
}
myPersonSlice := []Person{ {"John Doe",41},{"Peter Parker",17} }
for _,myPerson := range myPersonSlice{
t.Execute(os.Stdout,myPerson)
}
}
Playground
https://riptutorial.com/ 237
www.dbooks.org
Defining functions for calling from template
package main
import (
"fmt"
"net/http"
"os"
"text/template"
)
func main() {
var fns = template.FuncMap{
"status_code": func(x string) int {
resp, err := http.Head(x)
if err != nil {
return -1
}
return resp.StatusCode
},
}
req := new(Requests)
req.URLs = []string{"http://godoc.org", "http://stackoverflow.com", "http://linux.org"}
tmpl := template.Must(template.New("getBatch").Funcs(fns).Parse(requestTemplate))
err := tmpl.Execute(os.Stdout, req)
if err != nil {
fmt.Println(err)
}
}
Here we use our defined function status_code to get status code of web page right from template.
Output:
http://godoc.org 200
http://stackoverflow.com 200
http://linux.org 200
https://riptutorial.com/ 238
Chapter 64: Testing
Introduction
Go comes with its own testing facilities that has everything needed to run tests and benchmarks.
Unlike in most other programming languages, there is often no need for a separate testing
framework, although some exist.
Examples
Basic Test
main.go:
package main
import (
"fmt"
)
func main() {
fmt.Println(Sum(4,5))
}
main_test.go:
package main
import (
"testing"
)
$ go test
ok test_app 0.005s
https://riptutorial.com/ 239
www.dbooks.org
$ go test -v
=== RUN TestSum
--- PASS: TestSum (0.00s)
PASS
ok _/tmp 0.000s
$ go test -v ./...
ok github.com/me/project/dir1 0.008s
=== RUN TestSum
--- PASS: TestSum (0.00s)
PASS
ok github.com/me/project/dir2 0.008s
=== RUN TestDiff
--- PASS: TestDiff (0.00s)
PASS
Example:
go test -v run=TestSum
Benchmark tests
sum.go:
package sum
sum_test.go:
package sum
import "testing"
https://riptutorial.com/ 240
Then in order to run a simple benchmark:
$ go test -bench=.
BenchmarkSum-8 2000000000 0.49 ns/op
ok so/sum 1.027s
This type of testing is popular technique for testing with predefined input and output values.
package main
import (
"fmt"
)
func main() {
fmt.Println(Sum(4, 5))
}
After you run it with, you will see that the output is 9. Although the Sum function looks pretty simple,
it is a good idea to test your code. In order to do this, we create another file named main_test.go in
the same folder as main.go, containing the following code:
package main
import (
"testing"
)
https://riptutorial.com/ 241
www.dbooks.org
As you can see, a slice of anonymous structs is created, each with a set of inputs and the
expected result. This allows a large number of test cases to be created all together in one place,
then executed in a loop, reducing code repetition and improving clarity.
This type of tests make sure that your code compiles properly and will appear in the generated
documentation for your project. In addition to that, the example tests can assert that your test
produces proper output.
sum.go:
package sum
sum_test.go:
package sum
import "fmt"
func ExampleSum() {
x := Sum(1, 2)
fmt.Println(x)
fmt.Println(Sum(-1, -1))
fmt.Println(Sum(0, 0))
// Output:
// 3
// -2
// 0
}
To execute your test, run go test in the folder containing those files OR put those two files in a
sub-folder named sum and then from the parent folder execute go test ./sum. In both cases you will
get an output similar to this:
ok so/sum 0.005s
If you are wondering how this is testing your code, here is another example function, which
actually fails the test:
func ExampleSum_fail() {
x := Sum(1, 2)
fmt.Println(x)
// Output:
// 5
}
https://riptutorial.com/ 242
When you run go test, you get the following output:
$ go test
--- FAIL: ExampleSum_fail (0.00s)
got:
3
want:
5
FAIL
exit status 1
FAIL so/sum 0.006s
If you want to see the documentation for your sum package – just run:
go doc -http=:6060
https://riptutorial.com/ 243
www.dbooks.org
https://riptutorial.com/ 244
• A tearDown function does a rollback.
This is a good option when you can't modify your database and you need to create an object that
simulate an object brought of database or need to init a configuration in each test.
// First test
func TestOnePlusOne(t *testing.T) {
numbers["one"] = numbers["one"] + 1
if numbers["one"] != 2 {
t.Error("1 plus 1 = 2, not %v", value)
}
}
// Second test
func TestOnePlusTwo(t *testing.T) {
numbers["one"] = numbers["one"] + 2
if numbers["one"] != 3 {
t.Error("1 plus 2 = 3, not %v", value)
}
}
https://riptutorial.com/ 245
www.dbooks.org
func TestMain(m *testing.M) {
// You create an Person and you save in database
setUp(&Person{
ID: personID,
Name: personName,
Age: 19,
})
retCode := m.Run()
// When you have executed the test, the Person is deleted from database
tearDown(personID)
os.Exit(retCode)
}
if P.Name != personName {
t.Error("P.Name is %s and it must be Toni", P.Name)
}
}
Run go test as normal, yet with the coverprofile flag. Then use go tool to view the results as
HTML.
go test -coverprofile=c.out
go tool cover -html=c.out
https://riptutorial.com/ 246
Chapter 65: Text + HTML Templating
Examples
Single item template
Note the use of {{.}} to output the item within the template.
package main
import (
"fmt"
"os"
"text/template"
)
func main() {
const (
letter = `Dear {{.}}, How are you?`
)
Results in:
Note the use of {{range .}} and {{end}} to cycle over the collection.
package main
import (
"fmt"
"os"
"text/template"
)
func main() {
const (
letter = `Dear {{range .}}{{.}}, {{end}} How are you?`
)
https://riptutorial.com/ 247
www.dbooks.org
}
Results in:
In this example, a function map named funcMap is supplied to the template via the Funcs() method
and then invoked inside the template. Here, the function increment() is used to get around the lack
of a less than or equal function in the templating language. Note in the output how the final item in
the collection is handled.
A - at the beginning {{- or end -}} is used to trim whitespace and can be used to help make the
template more legible.
package main
import (
"fmt"
"os"
"text/template"
)
func main() {
const (
letter = `Dear {{with $names := .}}
{{- range $i, $val := $names}}
{{- if lt (increment $i) (len $names)}}
{{- $val}}, {{else -}} and {{$val}}{{end}}
{{- end}}{{end}}; How are you?`
)
Results in:
https://riptutorial.com/ 248
Templates with structs
package main
import (
"fmt"
"os"
"text/template"
)
func main() {
const (
letter = `------------------------------
{{range .}}{{.FirstName}} {{.LastName}}
{{.Street}}
{{.City}}, {{.State}} {{.Zip}}
Dear {{.FirstName}},
How are you?
------------------------------
{{end}}`
)
harry := Person{
FirstName: "Harry",
LastName: "Jones",
Street: "1234 Main St.",
City: "Springfield",
State: "IL",
Zip: "12345-6789",
}
jane := Person{
FirstName: "Jane",
LastName: "Sherman",
Street: "8511 1st Ave.",
City: "Dayton",
State: "OH",
Zip: "18515-6261",
}
https://riptutorial.com/ 249
www.dbooks.org
Results in:
------------------------------
Harry Jones
1234 Main St.
Springfield, IL 12345-6789
Dear Harry,
How are you?
------------------------------
Jane Sherman
8511 1st Ave.
Dayton, OH 18515-6261
Dear Jane,
How are you?
------------------------------
HTML templates
package main
import (
"fmt"
"html/template"
"os"
)
func main() {
const (
letter = `<html><body><table>
<tr><th></th><th>Name</th><th>Address</th></tr>
{{range .}}
<tr>
<td><img src="{{.AvatarUrl}}"></td>
<td>{{.FirstName}} {{.LastName}}</td>
<td>{{.Street}}, {{.City}}, {{.State}} {{.Zip}}</td>
</tr>
{{end}}
</table></body></html>`
)
https://riptutorial.com/ 250
fmt.Println(err.Error())
}
harry := Person{
FirstName: "Harry",
LastName: "Jones",
Street: "1234 Main St.",
City: "Springfield",
State: "IL",
Zip: "12345-6789",
AvatarUrl: "harry.png",
}
jane := Person{
FirstName: "Jane",
LastName: "Sherman",
Street: "8511 1st Ave.",
City: "Dayton",
State: "OH",
Zip: "18515-6261",
AvatarUrl: "jane.png",
}
Results in:
<html><body><table>
<tr><th></th><th>Name</th><th>Address</th></tr>
<tr>
<td><img src="harry.png"></td>
<td>Harry Jones</td>
<td>1234 Main St., Springfield, IL 12345-6789</td>
</tr>
<tr>
<td><img src="jane.png"></td>
<td>Jane Sherman</td>
<td>8511 1st Ave., Dayton, OH 18515-6261</td>
</tr>
</table></body></html>
First, here's what can happen when text/template is used for HTML. Note Harry's FirstName
property).
package main
import (
"fmt"
"html/template"
"os"
)
https://riptutorial.com/ 251
www.dbooks.org
type Person struct {
FirstName string
LastName string
Street string
City string
State string
Zip string
AvatarUrl string
}
func main() {
const (
letter = `<html><body><table>
<tr><th></th><th>Name</th><th>Address</th></tr>
{{range .}}
<tr>
<td><img src="{{.AvatarUrl}}"></td>
<td>{{.FirstName}} {{.LastName}}</td>
<td>{{.Street}}, {{.City}}, {{.State}} {{.Zip}}</td>
</tr>
{{end}}
</table></body></html>`
)
harry := Person{
FirstName: `Harry<script>alert("You've been hacked!")</script>`,
LastName: "Jones",
Street: "1234 Main St.",
City: "Springfield",
State: "IL",
Zip: "12345-6789",
AvatarUrl: "harry.png",
}
jane := Person{
FirstName: "Jane",
LastName: "Sherman",
Street: "8511 1st Ave.",
City: "Dayton",
State: "OH",
Zip: "18515-6261",
AvatarUrl: "jane.png",
}
Results in:
<html><body><table>
<tr><th></th><th>Name</th><th>Address</th></tr>
<tr>
<td><img src="harry.png"></td>
https://riptutorial.com/ 252
<td>Harry<script>alert("You've been hacked!")</script> Jones</td>
<td>1234 Main St., Springfield, IL 12345-6789</td>
</tr>
<tr>
<td><img src="jane.png"></td>
<td>Jane Sherman</td>
<td>8511 1st Ave., Dayton, OH 18515-6261</td>
</tr>
</table></body></html>
The above example, if accessed from a browser, would result in the script being executed an an
alert being generated. If, instead, the html/template were imported instead of text/template, the
script would be safely sanitized:
<html><body><table>
<tr><th></th><th>Name</th><th>Address</th></tr>
<tr>
<td><img src="harry.png"></td>
<td>Harry<script>alert("You've been hacked!")</script> Jones</td>
<td>1234 Main St., Springfield, IL 12345-6789</td>
</tr>
<tr>
<td><img src="jane.png"></td>
<td>Jane Sherman</td>
<td>8511 1st Ave., Dayton, OH 18515-6261</td>
</tr>
</table></body></html>
The second result would look garbled when loaded in a browser, but would not result in a
potentially malicious script executing.
https://riptutorial.com/ 253
www.dbooks.org
Chapter 66: The Go Command
Introduction
The go command is a command-line program that allows for the management of Go development.
It enables building, running, and testing code, as well as a variety of other Go-related tasks.
Examples
Go Run
go run will run a program without creating an executable file. Mostly useful for development. run
will only execute packages whose package name is main.
package main
import fmt
func main() {
fmt.Println("Hello, World!")
}
go run main.go
Output:
Hello, World!
Go Build
https://riptutorial.com/ 254
package main
import fmt
func main() {
fmt.Println("Hello, World!")
}
go build main.go
build creates an executable program, in this case: main or main.exe. You can then run this file to
see the output Hello, World!. You can also copy it to a similar system that doesn't have Go
installed, make it executable, and run it there.
Building a package
To build a package called main, you can simply use:
Go Clean
go clean will clean up any temporary files created when invoking go build on a program. It will also
clean files left over from Makefiles.
Go Fmt
go fmtwill format a program's source code in a neat, idiomatic way that is easy to read and
understand. It is recommended that you use go fmt on any source before you submit it for public
viewing or committing into a version control system, to make reading it easier.
https://riptutorial.com/ 255
www.dbooks.org
To format a file:
go fmt main.go
go fmt myProject
You can also use gofmt -s (not go fmt) to attempt to simplify any code that it can.
gofmt(not go fmt) can also be used to refactor code. It understands Go, so it is more powerful than
using a simple search and replace. For example, given this program (main.go):
package main
func main() {
e := &Example{"Hello"}
e.Original("Goodbye")
}
You can replace the method Original with Refactor with gofmt:
func main() {
e := &Example{"Hello"}
- e.Original("Goodbye")
+ e.Refactor("Goodbye")
}
Go Get
go get downloads the packages named by the import paths, along with their dependencies. It then
installs the named packages, like 'go install'. Get also accepts build flags to control the installation.
go get github.com/maknahar/phonecountry
https://riptutorial.com/ 256
When checking out a new package, get creates the target directory $GOPATH/src/<import-path>. If
the GOPATH contains multiple entries, get uses the first one. Similarly, it will install compiled
binaries in $GOPATH/bin.
When checking out or updating a package, get looks for a branch or tag that matches the locally
installed version of Go. The most important rule is that if the local installation is running version
"go1", get searches for a branch or tag named "go1". If no such version exists it retrieves the most
recent version of the package.
When using go get, the -d flag causes it to download but not install the given package. The -u flag
will allow it to update the package and its dependencies.
Go env
$go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/vikashkv/work"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7.4_1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7.4_1/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -
fdebug-prefix-map=/var/folders/xf/t3j24fjd2b7bv8c9gdr_0mj80000gn/T/go-build785167995=/tmp/go-
build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
If one or more variable names is given as arguments, it prints the value of each named
variable on its own line.
darwin
/Users/vikashkv/work
https://riptutorial.com/ 257
www.dbooks.org
Chapter 67: Time
Introduction
The Go time package provides functionality for measuring and displaying time.
This package provide a structure time.Time, allowing to store and do computations on dates and
time.
Syntax
• time.Date(2016, time.December, 31, 23, 59, 59, 999, time.UTC) // initialize
• date1 == date2 // returns true when the 2 are the same moment
• date1 != date2 // returns true when the 2 are different moment
• date1.Before(date2) // returns true when the first is strictly before the second
• date1.After(date2) // returns true when the first is strictly after the second
Examples
Return time.Time Zero Value when function has an Error
Time parsing
If you have a date stored as a string you will need to parse it. Use time.Parse.
fmt.Println(date)
// Prints 2017-04-08 00:00:00 +0000 UTC
The first parameter is the layout in which the string stores the date and the second parameter is
https://riptutorial.com/ 258
the string that contains the date. 01/02/2006 is the same than saying the format is MM/DD/YYYY.
The layout defines the format by showing how the reference time, defined to be Mon Jan 2 15:04:05
-0700 MST 2006 would be interpreted if it were the value; it serves as an example of the input
format. The same interpretation will then be made to the input string.
You can see the constants defined in the time package to know how to write the layout string, but
note that the constants are not exported and can't be used outside the time package.
const (
stdLongMonth // "January"
stdMonth // "Jan"
stdNumMonth // "1"
stdZeroMonth // "01"
stdLongWeekDay // "Monday"
stdWeekDay // "Mon"
stdDay // "2"
stdUnderDay // "_2"
stdZeroDay // "02"
stdHour // "15"
stdHour12 // "3"
stdZeroHour12 // "03"
stdMinute // "4"
stdZeroMinute // "04"
stdSecond // "5"
stdZeroSecond // "05"
stdLongYear // "2006"
stdYear // "06"
stdPM // "PM"
stdpm // "pm"
stdTZ // "MST"
stdISO8601TZ // "Z0700" // prints Z for UTC
stdISO8601SecondsTZ // "Z070000"
stdISO8601ShortTZ // "Z07"
stdISO8601ColonTZ // "Z07:00" // prints Z for UTC
stdISO8601ColonSecondsTZ // "Z07:00:00"
stdNumTZ // "-0700" // always numeric
stdNumSecondsTz // "-070000"
stdNumShortTZ // "-07" // always numeric
stdNumColonTZ // "-07:00" // always numeric
stdNumColonSecondsTZ // "-07:00:00"
)
Comparing Time
Sometime you will need to know, with 2 dates objects, if there are corresponding to the same date,
or find which date is after the other.
• date1 == date2, returns true when the 2 are the same moment
• date1 != date2, returns true when the 2 are different moment
• date1.Before(date2), returns true when the first is strictly before the second
• date1.After(date2), returns true when the first is strictly after the second
https://riptutorial.com/ 259
www.dbooks.org
WARNING: When the 2 Time to compare are the same (or correspond to the exact
same date), functions After and Before will return false, as a date is neither before nor
after itself
TIPS: If you need to know if a date is before or equal another one, just need to
combine the 4 operators
• date1 == date2 && date1.After(date2), returns true when date1 is after or equal
date2
or using ! (date1.Before(date2))
• date1 == date2 && date1.Before(date2), returns true when date1 is before or equal
date2 or using !(date1.After(date2))
bool9 := date1.After(date3) // false, because date1 is not after date3 (that are the same)
bool10:= date1.Before(date3) // false, because date1 is not before date3 (that are the same)
https://riptutorial.com/ 260
Chapter 68: Type conversions
Examples
Basic Type Conversion
As Go uses implicit interface implementation, you will not get a compile-time error if your struct
does not implement an interface you had intended to implement. You can test the implementation
explicitly using type casting: type MyInterface interface { Thing() }
This example illustrates how Go's type system can be used to implement some unit system.
package main
import (
"fmt"
)
https://riptutorial.com/ 261
www.dbooks.org
return KilometersPerHour(mps * 3.6)
}
func main() {
var mps MetersPerSecond
mps = 12.5
kmh := mps.toKilometersPerHour()
mps2 := kmh.toMetersPerSecond()
fmt.Printf("%vmps = %vkmh = %vmps\n", mps, kmh, mps2)
}
Open in Playground
https://riptutorial.com/ 262
Chapter 69: Variables
Syntax
• var x int // declare variable x with type int
• var s string // declare variable s with type string
• x = 4 // define x value
• s = "foo" // define s value
• y := 5 // declare and define y inferring its type to int
• f := 4.5 // declare and define f inferring its type to float64
• b := "bar" // declare and define b inferring its type to string
Examples
Basic Variable Declaration
Go is a statically typed language, meaning you generally have to declare the type of the variables
you are using.
// You can declare multiple variables of the same type in one line
var a, b, c string
If a function returns multiple values, you can also assign values to variables based on the
https://riptutorial.com/ 263
www.dbooks.org
function's return values.
x, y := multipleReturn() // x = 1, y = 2
w, z := multipleReturn2() // w = 3, z = 4
Blank Identifier
Go will throw an error when there is a variable that is unused, in order to encourage you to write
better code. However, there are some situations when you really don't need to use a value stored
in a variable. In those cases, you use a "blank identifier" _ to assign and discard the assigned
value.
A blank identifier can be assigned a value of any type, and is most commonly used in functions
that return multiple values.
func main() {
// I only want the sum, but not the product
sum, _ := SumProduct(1,2) // the product gets discarded
fmt.Println(sum) // prints 3
}
Using range
func main() {
https://riptutorial.com/ 264
There are some situations where you won't be sure what type a variable is when it is returned from
a function. You can always check a variable's type by using var.(type) if you are unsure what type
it is:
switch x := x.(type) {
case bool:
fmt.Printf("boolean %t\n", x) // x has type bool
case int:
fmt.Printf("integer %d\n", x) // x has type int
case string:
fmt.Printf("pointer to boolean %s\n", x) // x has type string
default:
fmt.Printf("unexpected type %T\n", x) // %T prints whatever type x is
}
https://riptutorial.com/ 265
www.dbooks.org
Chapter 70: Vendoring
Remarks
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.
Examples
Use govendor to add external packages
Govendor is a tool that is used to import 3rd party packages into your code repository in a way that
is compatible with golang's vendoring.
Say for example that you are using a 3rd party package bosun.org/slog:
package main
import "bosun.org/slog"
func main() {
slog.Infof("Hello World")
}
$GOPATH/src/
├── github.com/me/helloworld/
| ├── hello.go
├── bosun.org/slog/
| ├── ... (slog files)
Running the following command at your command prompt will grab all the external packages from
your Go package and package the required bits into a vendor folder:
govendor add +e
https://riptutorial.com/ 266
This instructs govendor to add all of the external packages into your current repository.
$GOPATH/src/
├── github.com/me/helloworld/
| ├── vendor/
| | ├── bosun.org/slog/
| | | ├── ... (slog files)
| ├── hello.go
and those who clone your repository will also grab the required 3rd party packages.
trash is a minimalistic vendoring tool that you configure with vendor.conf file. This example is for
trash itself:
# package
github.com/rancher/trash
github.com/Sirupsen/logrus v0.10.0
github.com/urfave/cli v1.18.0
github.com/cloudfoundry-incubator/candiedyaml 99c3df8
https://github.com/imikushin/candiedyaml.git
github.com/stretchr/testify v1.1.3
github.com/davecgh/go-spew 5215b55
github.com/pmezard/go-difflib 792786c
golang.org/x/sys a408501
The first non-comment line is the package we're managing ./vendor for (note: this can be literally
any package in your project, not just the root one).
Each non-empty and non-comment line lists one dependency. Only the "root" package of the
dependency needs to be listed.
After the package name goes the version (commit, tag or branch) and optionally the package
repository URL (by default, it's inferred from the package name).
To populate your ./vendor dir, you need to have vendor.conf file in the current dir and just run:
$ trash
Trash will clone the vendored libraries into ~/.trash-cache (by default), checkout requested
versions, copy the files into ./vendor dir and prune non-imported packages and test files. This
last step keeps your ./vendor lean and mean and helps save space in your project repo.
Note: as of v0.2.5 trash is available for Linux and macOS, and only supports git to retrieve
packages, as git's the most popular one, but we're working on adding all the others that go get
supports.
https://riptutorial.com/ 267
www.dbooks.org
Use golang/dep
Usage
Get the tool via
$ go get -u github.com/golang/dep/...
$ dep init
$ dep ensure -update
Note that the manifest and lock file formats have now been finalized. These will remain
compatible even as the tool changes.
Example vendor.json
"comment": "",
"ignore": "test",
"package": [
{
"checksumSHA1": "kBeNcaKk56FguvPSUCEaH6AxpRc=",
"path": "github.com/golang/protobuf/proto",
"revision": "2bba0603135d7d7f5cb73b2125beeda19c09f4ef",
"revisionTime": "2017-03-31T03:19:02Z"
},
{
"checksumSHA1": "1DRAxdlWzS4U0xKN/yQ/fdNN7f0=",
"path": "github.com/syndtr/goleveldb/leveldb/errors",
https://riptutorial.com/ 268
"revision": "8c81ea47d4c41a385645e133e15510fc6a2a74b4",
"revisionTime": "2017-04-09T01:48:31Z"
}
],
"rootPath": "github.com/sample"
https://riptutorial.com/ 269
www.dbooks.org
Chapter 71: Worker Pools
Examples
Simple worker pool
package main
import (
"fmt"
"sync"
)
func main() {
// make our channels for communicating work and results
jobs := make(chan job, 100) // 100 was chosen arbitrarily
results := make(chan result, 100)
https://riptutorial.com/ 270
for {
jobs <- getJob() // I haven't defined getJob() and noMoreJobs()
if noMoreJobs() { // they are just for illustration
break
}
}
}()
A job queue that maintains a worker pool, useful for doing things like background processing in
web servers:
package main
import (
"fmt"
"runtime"
"strconv"
"sync"
"time"
)
https://riptutorial.com/ 271
www.dbooks.org
workers[i] = NewWorker(readyPool, workersStopped)
}
return &JobQueue{
internalQueue: make(chan Job),
readyPool: readyPool,
workers: workers,
dispatcherStopped: sync.WaitGroup{},
workersStopped: workersStopped,
quit: make(chan bool),
}
}
https://riptutorial.com/ 272
go func() {
w.done.Add(1)
for {
w.readyPool <- w.assignedJobQueue // check the job queue in
select {
case job := <-w.assignedJobQueue: // see if anything has been assigned to the queue
job.Process()
case <-w.quit:
w.done.Done()
return
}
}
}()
}
func main() {
queue := NewJobQueue(runtime.NumCPU())
queue.Start()
defer queue.Stop()
https://riptutorial.com/ 273
www.dbooks.org
Chapter 72: XML
Remarks
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.
Examples
Basic decoding / unmarshalling of nested elements with data
XML elements often nest, have data in attributes and/or as character data. The way to capture this
data is by using ,attr and ,chardata respectively for those cases.
var doc = `
<parent>
<child1 attr1="attribute one"/>
<child2>and some cdata</child2>
</parent>
`
func main() {
var obj parent
err := xml.Unmarshal([]byte(doc), &obj)
if err != nil {
log.Fatal(err)
}
fmt.Println(obj.Child2.Cdata1)
https://riptutorial.com/ 274
Playground
https://riptutorial.com/ 275
www.dbooks.org
Chapter 73: YAML
Examples
Creating a config file in YAML format
import (
"io/ioutil"
"path/filepath"
"gopkg.in/yaml.v2"
)
func main() {
filename, _ := filepath.Abs("config/config.yml")
yamlFile, err := ioutil.ReadFile(filename)
var config Config
err = yaml.Unmarshal(yamlFile, &config)
if err != nil {
panic(err)
}
//env can be accessed from config.Env
}
//config.yml should be placed in config/config.yml for example, and needs to have the
following line for the above example:
//env: test
https://riptutorial.com/ 276
Chapter 74: Zero values
Remarks
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.
Examples
Basic Zero Values
Variables in Go are always initialized whether you give them a starting value or not. Each type,
including custom types, has a zero value they are set to if not given a value.
This also applies to maps, slices, channels and function types. These types will initialize to nil. In
arrays, each element is initialized to the zero value of its respective type.
Use make to create a slice populated with values, any values created in the slice are set to the zero
value of the type of the slice. For instance:
In this example, myIntSlice is a int slice that contains 5 elements which are all 0 because that's
the zero value for the type int.
You can also create a slice with new, this will create a pointer to a slice.
https://riptutorial.com/ 277
www.dbooks.org
Note: Slice pointers don't support indexing so you can't access the values using myIntSlice[3],
instead you need to do it like (*myIntSlice)[3].
When creating a struct without initializing it, each field of the struct is initialized to its respective
zero value.
func main() {
var myZero = ZeroStruct{}
fmt.Printf("Zero values are: %q, %d, %t\n", myZero.myString, myZero.myInt, myZero.myBool)
// Prints "Zero values are: "", 0, false"
}
Arrays do not need to be initialized explicitly; the zero value of an array is a ready-to-
use array whose elements are themselves zeroed
For example, myIntArray is initialized with the zero value of int, which is 0:
https://riptutorial.com/ 278
Chapter 75: Zero values
Examples
Explanation
Zero values or zero initialization are simple to implement. Coming from languages like Java it may
seem complicated that some values can be nil while others are not. In summary from Zero Value:
The Go Programming Language Specification:
Pointers, functions, interfaces, slices, channels, and maps are the only types that can
be nil. The rest are initializated to false, zero, or empty strings based on their
respective types.
The zero value will be false even before implementation. Unit tests dependant on the return of this
function could be giving false positives/negatives.
package main
import "fmt"
func main() {
_, err := isAlive()
if err != nil {
fmt.Printf("ERR: %s\n", err.Error())
}
play it on playground
When returning both a struct and an error you need a User structure for return, which is not very
elegant. There are two counter-options:
https://riptutorial.com/ 279
www.dbooks.org
For example, the following code returns a pointer:
https://riptutorial.com/ 280
Credits
S.
Chapters Contributors
No
Best practices on
4 Iman Tumorang
project structure
9 Closures abhink
https://riptutorial.com/ 281
www.dbooks.org
SommerEngineering, sztanpet, Zoyd
15 Cryptography SommerEngineering
Developing for
Multiple Platforms
17 ecem
with Conditional
Compiling
Executing
19 Krzysztof Kowalczyk, Kyle Brandt, Nevermore
Commands
24 gob zola
25 Goroutines mohan08p
28 Images putu
30 Installation sadlil
https://riptutorial.com/ 282
4444, Florian Hämmerle, Ingve, mohan08p, Sam Whited,
32 Iota
Wojciech Kazior, Zoyd
JWT Authorization in
34 AniSkywalker
Go
Object Oriented
43 Davyd Dzhahaiev, Sam Whited, zola
Programming
46 Panic and Recover JunLe Meng, Kaedys, Kristoffer Sall-Storgaard, Sam Whited
Parsing Command
47 Line Arguments And Ingve, Pavel Kazhevets, Sam Whited
Flags
https://riptutorial.com/ 283
www.dbooks.org
49 Plugin Sam Whited
Profiling using go
51 mbb, Nevermore, radbrawler
tool pprof
52 Protobuf in Go mohan08p
55 Select and Channels Harshal Sheth, Kaedys, RamenChef, Sam Whited, Utahcon
Text + HTML
63 Stephen Rudolph
Templating
https://riptutorial.com/ 284
67 Variables Community, FredMaggiowski, Jon Chan, Simone Carletti
https://riptutorial.com/ 285
www.dbooks.org