Go(lang)
I 'learned' Go once, forgot almost everything, came here for a refresher and found that I had crappy notes. So I'm rebuilding the notes in a way that should be useful to future-me. http://godashboard.appspot.com/project
Basics
- Uses func main (similar to C), a program also starts in package main
Import
import ( "packageA" "packageB" )
- Unused imports throw an error
Functions
Basic
func add(x int, y int) int {
return x + y
}
Multi-return
func swap(a, b int) (int, int) {
return b, a
}
Named results
func sumProd(x, y int) (sum, prod) {
sum = x + y
prod = x * y
return
}
Function are values too and can be assigned, referenced and passed around.
Closure
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
Variables
Go is strongly typed, but uses inference as much as possible. So this is possible
var x int x = 5
But better is
x := 5
Types
- bool
- string
- int{8,16,32,64}
- uint{8,16,32,64}, uintptr
- byte (same as uint8)
- rune (same as uint32, represents unicode point)
- float{32,64}
- complex{64,128}
Pointers
Go has pointers, but no pointer arithmetic.
v := Vertex{1,2}
p := &v
p.X = 5
Structs
A Struct (this can be set in package space, I don't know if it can be declared in a function)
type Vertex struct {
X int
Y int
}
v := Vertex{1,2}
fmt.Println(v.X)
A struct literal.
var ( name := "Adam" i := 1 )
Structs are the closes thing to classes in Go
Methods
Methods take a struct before the method name, this is the struct they are a method on
func(v *Vertex) Abs() float64 {
return math.Sqrt( v.X*v.X + v.Y*v.Y )
}
You can define a method for any type in your package, but not for a struct from another package.
Interfaces
Interfaces define a set of attribute. A struct satisfies an interface when it has all the attributes the interface defines. Golang.org reference
For
The only looping structure is for.
Traditional
for i := 0 ; i<10 ; i++ {
fmt.Println(i)
}
As While
i: = 5
for i<100 {
i += 3
}
Infinite Loop
for {
fmt.Println("There is no escape")
}
Range
a := []int{3,1,4,1,5,9,2,6,5}
for i,v := range a {
fmt.Println(i, v)
}
Range without index. This can be important because unused variables throw errors.
a := []int{3,1,4,1,5,9,2,6,5}
for _,v := range a {
fmt.Println(v)
}
If
Basic
func abs(x float64) float64 {
if x<0 {
return -x
}
return x
}
Much like for, there is a space for a statement scoped to the if block before the conditional
func pow(x, n, lim float64) float64 {
if v := math.Pow(x,n) ; v < lim {
return v
}
return lim
}
Else. Not shown here, but the pre-statement is scoped to the else block as well
if foo {
fmt.Println("Foo is true")
} else {
fmt.println("Foo is not true")
}
New
New allocates something and returns a pointer.
v := new(Vertex) x.X = 5
Maps
Like a dictionary, must be created with make
m = make(map[string]int) m["Adam"] = 28 m["Lauren"] = 26
Map literal
var m = map[string]int{
"Adam": 28,
"Lauren": 26,
}
var n = map[string]Vertex{
"Home": {10,20}
"Work": {25,40}
}
Delete (using previous examples)
delete(m, "Adam")
Slice
A slice points to a slice of an array. It does this with a pointer and a length
s: = []int{3,1,4,1,5,9,2,6}
Switch
switch pre := something; condition{
case "A":
// handle A
case "B":
//do B stuff
fallthrough
case "C":
//do stuff for C and B
default:
//default stuff
}
A switch with no condition evaluates each case, can act like a large if-else chain
switch{
case a > 10:
//do something
case a > 5:
//do something else
//this is actually 10 >= a > 5
default:
//all others, final else
}