Go(lang)

From Adam Colton
Jump to navigation Jump to search

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

https://github.com/chsc/GoGL

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
 }