Skip to content

Instantly share code, notes, and snippets.

@RobAWilkinson
Created March 2, 2015 04:30
Show Gist options
  • Save RobAWilkinson/ee459e855515eb2d67a4 to your computer and use it in GitHub Desktop.
Save RobAWilkinson/ee459e855515eb2d67a4 to your computer and use it in GitHub Desktop.

#Intro to Golang

###What is go

  • statically typed
  • functional language
  • with concurrency built right in

###set up

  • Install go brew install go --cross-compile-common
  • All your gocode lives inside a go directory which we need to make mkdir $HOME/go
  • then add this as a path within your bash_profile
  • export GOPATH=$HOME/go
  • export PATH=$PATH:$GOPATH/bin

hello world

open a new file hello_world.go in sublime

package main

import "fmt"

func main() {
  fmt.Println("hello")
}

###Types

Go is a statically typed language!

That means that when you creata variable, it can only hold a certain datatype. Example

func main() {
  var name string
  name = "Rob"

  fmt.Println(name)
}

Or you can declare the variables type and value explicitly in one line

var name string = "Rob"

In this case we are assigning a string to a variable of type string, this type checks and no error is thrown If you change the name variables type from string to int however, the compiler will throw an error.

Talk with the people on your table and discuss the advantages and disadvantages of having statically typed vs dynamically typed languages.

###Go Smart Typing Its possible in Golang to the declare the variable and to assign that variable in one line.

We can do this with the := operator (thats a colon followed by an equal sign) Lets convert our printname function to use this new operator

func main() {
  name := "Rob"
  
  fmt.Println(name)
}

The type is declared and the variable assigned in the one line, the type of name is still string.

Sidenote: if you ever need to check the type of a variable you can import the reflect package and call reflect.TypeOf() on the varaible)

If we try to reassign our name variable to a integer, our compiler will throw an error

name := "Rob"
name = 12 // throws an error

###Arrays in Go

Arrays in go are not like in ruby/javascript, when you create an array the computer needs to assign it memory space, so it needs to know what size it is, you set this up like this

  // declare the array
  var arr [5]int

  // then set and get elements just like we've seen before
  arr[0] = 10
  arr[1] = 47
  arr[2] = 5
  arr[3] = 5
  arr[4] = 5
  fmt.Println("array: ",arr)

We can decalre and create it in one line like so as well

arr := []int{10,47,5,5,5}

We can use len() to get the length of an array

Notice we declare the array with the amount of elements that are inside of it, not the index that it goes up to

if I add another line of code in here arr[5] = "hello world" it will throw 2 errors? What are they?

Notice that their is no append function!! Go has another type for that slices

###Slices

Slices are what got me excited about Go Slices are like arrays with a more powerful interface

Unlike arrays, slices are typed only by the elements they contain, not by the number of elements

To create a slice we just use the built in make function

slicey := make([]string,3)

We declare a new slice with an inital length of 3.
We can set and get elements on it just like we can on regular arrays Additionally, we can also make use of the append function with a slice Example:

slicey = append(slicey,"h")

lets create some elements in our slice and Ill show you the other operators

fmt.Println("sliced 2:5:",slicey[2:5])
fmt.Println("sliced :4",slicey[:4])
fmt.Println("sliced 3:", slicey[3:])

###Maps

The last datatype that were going to get into today is maps

this is almost like a hash in ruby and javascript

the syntax is make(map[KEY-TYPE]VALUE-TYPE)

We set and get values the same as we do in ruby/javascript

mappy := make(map[string]string)
mappy["k1"] = "value1"
mappy["k2"] = "value2"

You can declare and initialize a new map in one line if you want

mappy := map[string]string{"k1": "value1", "k2": "value2"}

###Functions in Golang Just like other things in go we have declare they functions inputs and outputs in go, What do you guys think this function does?

func sayhi(name string, times int) string {
  var names string
  for i := 0; i <= times; i++ {
    names += "hello" + name
  }
  return names
}

Whats the line after we declare the arguments do? Make a function that takes two integers and returns an array made of them

If your types are the same in the inputs you can save yourself a line Example:

func add(a, b int) int {
  return a + b
}

Functions can return more than one value as well, for example:

func returnTwo() (int, int) {
  return 1,2
}

and we use it like so

one, two = returnTwo()

You'll often see functions that return two things, something and an error you'll see somethign like this pretty often in go

value, err := returnChecker()
  if err {
    fmt.Println("there was an error", err)
  } else {
  // do something with the value
}

Functions can also take more than one argument, these are called variadic functions Example:

func sum(nums...int) {
  fmt.Print(nums," ")
  total := 0 
  for _, num := range nums {
    total := num
  }
  fmt.Println(total)
}

Using this as an example in your own time create a function that takes any amount of integers and converts them into an array

###Pointers

A pointer is just a signpost to a place in memore, I've always heard it said as its easier to give directions to the fridge than it is to carry it around with you. go uses them exactly like every other language I've used that has them

Guess what will be printed when we run this code

func tenval(initalValue int) {
  initialvalue = 10
}

func tenptr(initialValue *int)
  *initalValue = 10
}

func main() {
  i := 1
  fmt.Println(i)

  tenval(i)
  fmt.Println(i)

  tenptr(&i)
  fmt.Println(i)

  fmt.Println(&i)

###structs

  • Go’s structs are typed collections of fields. They’re useful for grouping data together to form records.
type Tree struct {
  left *Tree
  value int
  right *Tree
}

Or

type Person struct {
  firstName, lastname string
  age int
}

and we create a person with curly braces

rob := Person{"rob","wilkinson",26}

###Interfaces
* Interfaces are a set of methods but theyre also a type
Heres a simply example, in practice theyre incredubly useful because you can define a set of general methods and apply them to various different structs

type namer interface { fullName() string }

func (p Person) fullName() string { return p.firstName + " " + p.lastName } func main() { fmt.Println(rob.fullName()) }


Heres a great blog post on them <http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go>

###Concurrency
> Do not communicate by sharing memory; instead, share memory by communicating.

Concurrency in go involves two things **goroutines** and **channels**

A goroutine is non blocking, it starts running asynchronously as soon as it is executed`

func f(from string) { for i := 0; i < 3; i++ { fmt.Println(from, ":", i) } } func main() { f("direct") go f("goroutine") go func(msg string) { fmt.Println(msg) }("going") }


we can send values to and from channels by using ```<-```

ch <- v // Send v to channel ch. v := <-ch // Receive from ch, and // assign value to v. ``

We can pass a channel into a set goroutine and block until our code is ready

func worker(done chan bool) {
  fmt.Print("working...")
  time.Sleep(time.Second)
  fmt.Print("done")
  done <- true
}
func main() {
  done := make(chan bool, 1)
  go worker(done)
  <-done
}

Concurrency in Go involves two things:

  1. goroutines
  2. channels
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment