Go Cheat Sheet
Index
- Basic Syntax
- Operators
- Declarations
- Functions
- Type Conversions
- Control structures
- Arrays, Slices, Ranges
- Maps
- Structs
- Pointers
- Errors
- Output
Credits
This is based on https://github.com/a8m go-lang cheat sheet but slightly updated for my own use.
Also useful is https://golang.org/ref/spec
Go in a Nutshell
- Imperative language
- Statically typed
- Compiles to native code (no JVM)
- Structs with methods
- Interfaces
- No implementation inheritance.
- Functions are first class citizens
- Functions can return multiple values
- Closures
- Pointers
- Built-in concurrency primitives: Goroutines and Channels
Basic Syntax
Hello World
File hello.go
:
package main
import "fmt"
func main() {
fmt.Println("Hello Go")
}
$ go run hello.go
Operators
Arithmetic
Operator |
Description |
+ |
addition |
- |
subtraction |
* |
multiplication |
/ |
quotient |
% |
remainder |
& |
bitwise and |
| |
bitwise or |
^ |
bitwise xor |
&^ |
bit clear (and not) |
<< |
left shift |
>> |
right shift |
Comparison
Operator |
Description |
== |
equal |
!= |
not equal |
< |
less than |
<= |
less than or equal |
> |
greater than |
>= |
greater than or equal |
Logical
Operator |
Description |
&& |
logical and |
|| |
logical or |
! |
logical not |
Other
Operator |
Description |
& |
address of / create pointer |
* |
dereference pointer |
<- |
send / receive operator (see 'Channels' below) |
Declarations
Type goes after identifier!
var foo int // declaration without initialization
var foo int = 42 // declaration with initialization
var foo, bar int = 42, 1302 // declare and init multiple vars at once
var foo = 42 // type omitted, will be inferred
foo := 42 // shorthand, only in func bodies, omit var keyword, type is always implicit
const constant = "This is a constant"
var( // declare multiple variables
foo = 10
bar = 42
)
Basic Types - https://tour.golang.org/basics/11
Scope Definition - https://www.golang-book.com/books/intro/4
Functions
// a simple function
func functionName() {}
// function with parameters (again, types go after identifiers)
func functionName(param1 string, param2 int) {}
// multiple parameters of the same type
func functionName(param1, param2 int) {}
// return type declaration
func functionName() int {
return 42
}
// Can return multiple values at once
func returnMulti() (int, string) {
return 42, "foobar"
}
var x, str = returnMulti()
// Return multiple named results simply by return
func returnMulti2() (n int, s string) {
n = 42
s = "foobar"
// n and s will be returned
return
}
var x, str = returnMulti2()
Functions As Values And Closures
func main() {
// assign a function to a name
add := func(a, b int) int {
return a + b
}
// use the name to call the function
fmt.Println(add(3, 4))
}
// Closures
function main() {
b := 0
incr := func() int {
b++
return b
}
fmt.Println(incr()) //b prints 1
fmt.Println(incr()) //b prints 2
}
Type Conversions
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
// alternative syntax
i := 42
f := float64(i)
u := uint(f)
Control structures
If
func main() {
// Be aware that in an variable scope inside an if statement
// https://stackoverflow.com/questions/24475153/golang-variable-scope-inside-if-statements
// Basic one
if x > 0 {
return x
} else {
return -x
}
// You can put one statement before the condition
if a := b + c; a < 42 {
return a
} else {
return a - 42
}
// Type assertion inside if
var val interface{}
val = "foo"
if str, ok := val.(string); ok {
fmt.Println(str)
}
}
Loops
// There's only `for`, no `while`, no `until`
for i := 1; i < 10; i++ {
}
for ; i < 10; { // while - loop
}
for i < 10 { // you can omit semicolons if there is only a condition
}
for { // you can omit the condition ~ while (true)
}
Switch
// switch statement
switch operatingSystem {
case "darwin":
fmt.Println("Mac OS Hipster")
// cases break automatically, no fallthrough by default
case "linux":
fmt.Println("Linux Geek")
default:
// Windows, BSD, ...
fmt.Println("Other")
}
// as with for and if, you can have an assignment statement before the switch value
switch os := runtime.GOOS; os {
case "darwin": ...
}
// you can also make comparisons in switch cases
number := 42
switch {
case number < 42:
fmt.Println("Smaller")
case number == 42:
fmt.Println("Equal")
case number > 42:
fmt.Println("Greater")
}
// cases can be presented in comma-separated lists
var char byte = '?'
switch char {
case ' ', '?', '&', '=', '#', '+', '%':
fmt.Println("Should escape")
}
Arrays, Slices, Ranges
Arrays
var a [10]int // declare an int array with length 10. Array length is part of the type!
a[3] = 42 // set elements
i := a[3] // read elements
// declare and initialize
var a = [2]int{1, 2}
a := [2]int{1, 2} //shorthand
a := [...]int{1, 2} // elipsis -> Compiler figures out array length
Slices
var a []int // declare a slice - similar to an array, but length is unspecified
var a = []int {1, 2, 3, 4} // declare and initialize a slice (backed by the array given implicitly)
a := []int{1, 2, 3, 4} // shorthand
chars := []string{0:"a", 2:"c", 1: "b"} // ["a", "b", "c"]
var b = a[lo:hi] // creates a slice (view of the array) from index lo to hi-1
var b = a[1:4] // slice from index 1 to 3
var b = a[:3] // missing low index implies 0
var b = a[3:] // missing high index implies len(a)
a = append(a,17,3) // append items to slice a
c := append(a,b...) // concatenate slices a and b
// create a slice with make
a = make([]byte, 5, 5) // first arg length, second capacity
a = make([]byte, 5) // capacity is optional
// create a slice from an array
x := [3]string{"Лайка", "Белка", "Стрелка"}
s := x[:] // a slice referencing the storage of x
Maps or Hash Table
var m map[string]int
m = make(map[string]int)
m["key"] = 42
fmt.Println(m["key"])
delete(m, "key")
elem, ok := m["key"] // test if key "key" is present and retrieve it, if so
// map literal
var m = map[string]Vertex{
"Bell Labs": {40.68433, -74.39967},
"Google": {37.42202, -122.08408},
}
Structs
There are no classes, only structs. Structs can have methods.
// A struct is a type. It's also a collection of fields
// Declaration
type Vertex struct {
X, Y int
}
// Creating
var v = Vertex{1, 2}
var v = Vertex{X: 1, Y: 2} // Creates a struct by defining values with keys
var v = []Vertex{{1,2},{5,2},{5,5}} // Initialize a slice of structs
// Accessing members
v.X = 4
// You can declare methods on structs. The struct you want to declare the
// method on (the receiving type) comes between the the func keyword and
// the method name. The struct is copied on each method call(!)
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
// Call method
v.Abs()
// For mutating methods, you need to use a pointer (see below) to the Struct
// as the type. With this, the struct value is not copied for the method call.
func (v *Vertex) add(n float64) {
v.X += n
v.Y += n
}
Pointers
i, j = 42, 2701
p := &i // p points to the address of i
fmt.Println(*p) //read i through the pointer p
*p = 21 //update i through the pointer p
fmt.Println(i) //see new value of i
p = &j //point to the address of j
*p = *p / 37 //divide j through the pointer p
fmt.Println(j) //see new value of j
//*p - is the value that is stored at the address pointed to by x
//&p - is the memory address that x points to
//https://tour.golang.org/moretypes/1
//No pointer arithmetic
Errors
There is no exception handling. Functions that might produce an error just declare an additional return value of type Error
. This is the Error
interface:
func doStuff() (int, error) {
}
func main() {
result, err := doStuff()
if err != nil {
// handle error
} else {
// all is good, use result
}
}
Output
fmt.Println("Hello, 你好, नमस्ते, Привет, ᎣᏏᏲ") // basic print, plus newline
fmt.Printf("%d hex:%x bin:%b fp:%f sci:%e",17,17,17,17.0,17.0) // c-ish format
hellomsg := `
"Hello" in Chinese is 你好 ('Ni Hao')
"Hello" in Hindi is नमस्ते ('Namaste')
` // multi-line string literal, using back-tick at beginning and end
0