Welcome to the nice world of Golang

← and → to move between the slides

Presentation

Bruno Michel

History

Once upon a time...

Compiling

http://xkcd.com/303/ - CC by nc 2.5

The full story

Less is exponentially more

by Rob Pike

Why speaking of Go now?

Go1 is used in production

Basic features of Go

Hello World

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}

Declarations

var a int
var b bool
a = 15
b = false

a := 15
b := false

Functions

func hello(who string) string {
    return fmt.Sprintf("Hello %s", who)
}

func fibo(a, b int) (int, int) {
    a, b = a+b, a
    return a, b
}

incr := func(n int) int {
    return n+1
}

Control statements

if x > y {
    return x
} else {
    return y
}
const nb = 10
for i := 0; i < nb; i++ {
    fmt.Printf("Iteration n°%d\n", i)
}

Array / Slice

var array [10]int
var slice []int
list := []string{"a", "b", "c", "d", "e", "f"}
other := append(list[0:2], list[3:5]...)
for k, v := range other {
    fmt.Printf("%d -> %s\n", k, v)
}
// 0 -> a
// 1 -> b
// 2 -> d
// 3 -> e

Maps

data := map[string]string{
    "foo": "bar",
    "hello": "world",
}
for k, v := range data {
    fmt.Printf("%s -> %s\n", k, v)
}
// hello -> world
// foo -> bar

Packages

package even

func Even(i int) bool {
    return i%2 == 0
}

func odd(i int) bool {
    return i%2 == 1
}

// Even is exported

Import (
    "./even"
    "fmt"
    "os"
)

os.Open(filename)
fmt.Printf("Hello")
even.Even(4)
// Doesn't work:
// even.odd(3)

Error handling

f, err := os.Open(name)
if err != nil {
    return err
}
if d, err := f.Stat(); err != nil {
    return err
}
doSomething(f, d)

Defer

func foobar(name string) error {
    f, err := os.Open(name)
    if err != nil {
        return err
    }
    defer f.Close()
    fmt.Printf("%v", f)
    return nil
}

Methods

type Point struct {
    x float64
    y float64
}

func (start *Point) Distance(stop *Point) float64 {
    sqr := math.Pow(stop.x-start.x, 2)
    sqr += math.Pow(stop.y-start.y, 2)
    return math.Sqrt(sqr)
}

p1 := &Point{2.1, 51.0}
p2 := &Point{2.4, 42.0}
dst := p1.Distance(p2)

Concurrency in Go

Concurrency

Programming as the composition of independently executing processes.

Parallelism

Programming as the simultaneous execution of (possibly related) computations.

Concurrency vs. parallelism

One is about structure, one is about execution.

Goroutine

func computation(n int) {
    time.Sleep(n * time.Milliseconds)
    fmt.Printf("%s seconds elapsed\n", n)
}
go computation(1)
go computation(3)
go computation(5)
computation(7)

Channels

func pingpong(ch chan int) {
    n := <-ch
    fmt.Printf("Received %d\n", n)
    ch <- n
}

func main() {
    ch := make(chan int)
    go pingpong(ch)
    ch <- 42
    <-ch
}

Don't communicate by sharing memory

Share memory by communicating

Generator

func idGenerator() chan int {
    ids := make(chan int)
    go func() {
        id := 0
        for {
            ch <- id
            id++
        }
    }
    return ids
}

ids := idGenerator()
id1 := <-ids
id2 := <-ids

Select

select {
    case c1 <- n:
        fmt.Printf("c1")
    case s := <-c2:
        fmt.Printf("c2")
    case s := <-c3:
        fmt.Printf("c3")
}

Timeout

timeout := time.After(2 * time.Seconds)
select {
    case n := <-ch:
        fmt.Printf("Received %d", n)
    case <-timeout
        fmr.Printf("Too late")
}

Goroutines + Channels = <3

Increase your productivity

Readable code

No free

Interfaces

Interfaces

// crypto/cypher
type Block interface {
    BlockSize() int
    Encrypt(src, dst []byte)
    Decrypt(src, dst []byte)
}

Interfaces

A modern standard library

Go tools are awesome!

godoc

% godoc net/http Handle
PACKAGE

package http
    import "net/http"


FUNCTIONS

func Handle(pattern string, handler Handler)
    Handle registers the handler for the given pattern in the
    DefaultServeMux. The documentation for ServeMux explains how patterns
    are matched.

...

godoc -src

% godoc -src net/http Handle
// Handle registers the handler for the given pattern.
// If a handler already exists for pattern, Handle panics.
func (mux *ServeMux) Handle(pattern string, handler Handler) {
    mux.mu.Lock()
    defer mux.mu.Unlock()

    if pattern == "" {
        panic("http: invalid pattern " + pattern)
    }
    if handler == nil {
        panic("http: nil handler")
    }
    if mux.m[pattern].explicit {
        panic("http: multiple registrations for " + pattern)
    }

...

Avantages

Conclusion

The future of Go

Conclusion

That's all folks

Questions?