Go Cheatsheet
Hello, World!
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) string {
return "Hello, " + name + "!"
}
Variables
Variable declaration
var msg string
var msg = "Hello, world!"
var msg string = "Hello, world!"
var x, y int
var x, y int = 1, 2
var x, msg = 1, "Hello, world!"
msg = "Hello"
Declaration list
Shortcut of above (Infers type)
Constants
const Phi = 1.618
const Size int64 = 1024
const x, y = 1, 2
const (
Pi = 3.14
E = 2.718
)
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
Constants can be character, string, boolean, or numeric values.
See: Constants
Basic types
Strings
Strings are of type string
.
Numbers
Typical types
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias for uint8)
Other types
Arrays
Arrays have a fixed size.
Slices
Slices have a dynamic size, unlike arrays.
Pointers
Pointers point to a memory location of a variable. Go is fully garbage-collected.
See: Pointers
Type conversions
See: Type conversions
Flow control
Conditional
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}
See: If
Statements in if
A condition in an if
statement can be preceded with a statement before a ;
. Variables declared by the statement are only in scope until the end of the if
.
See: If with a short statement
Switch
switch day {
case "sunday":
// cases don't "fall through" by default!
fallthrough
case "saturday":
rest()
default:
work()
}
See: Switch
For loop
See: For loops
For-Range loop
entry := []string{"Jack","John","Jones"}
for i, val := range entry {
fmt.Printf("At position %d, the character %s is present\n", i, val)
}
See: For-Range loops
While loop
See: Go's "while"
Functions
Lambdas
Functions are first class objects.
Multiple return types
Named return values
By defining the return value names in the signature, a return
(no args) will return variables with those names.
See: Named return values
Packages
Importing
Both are the same.
See: Importing
Aliases
Exporting names
Exported names begin with capital letters.
See: Exported names
Packages
Every package file has to start with package
.
Concurrency
Goroutines
func main() {
// A "channel"
ch := make(chan string)
// Start concurrent routines
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Read 3 results
// (Since our goroutines are concurrent,
// the order isn't guaranteed!)
fmt.Println(<-ch, <-ch, <-ch)
}
Channels are concurrency-safe communication objects, used in goroutines.
See: Goroutines, Channels
Buffered channels
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!
Buffered channels limit the amount of messages it can keep.
See: Buffered channels
Closing channels
Closes a channel
Iterates across a channel until its closed
Closed if ok == false
See: Range and close
WaitGroup
import "sync"
func main() {
var wg sync.WaitGroup
for _, item := range itemList {
// Increment WaitGroup Counter
wg.Add(1)
go doOperation(&wg, item)
}
// Wait for goroutines to finish
wg.Wait()
}
func doOperation(wg *sync.WaitGroup, item string) {
defer wg.Done()
// do operation on item
// ...
}
A WaitGroup waits for a collection of goroutines to finish. The main goroutine calls Add to set the number of goroutines to wait for. The goroutine calls wg.Done()
when it finishes.
See: WaitGroup
Error control
Defer
Defers running a function until the surrounding function returns. The arguments are evaluated immediately, but the function call is not ran until later.
Deferring functions
Lambdas are better suited for defer blocks.
func main() {
var d = int64(0)
defer func(d *int64) {
fmt.Printf("& %v Unix Sec\n", *d)
}(&d)
fmt.Print("Done ")
d = time.Now().Unix()
}
Structs
Defining
See: Structs
Literals
You can also put field names.
Pointers to structs
Doing v.X
is the same as doing (*v).X
, when v
is a pointer.
Methods
Receivers
There are no classes, but you can define functions with receivers.
See: Methods
Mutation
By defining your receiver as a pointer (*Vertex
), you can do mutations.
See: Pointer receivers
Interfaces
A basic interface
Struct
Struct Rectangle
implicitly implements interface Shape
by implementing all of its methods.
Methods
func (r Rectangle) Area() float64 {
return r.Length * r.Width
}
func (r Rectangle) Perimeter() float64 {
return 2 * (r.Length + r.Width)
}
The methods defined in Shape
are implemented in Rectangle
.