Go Programming Language – Introduction



Go Programming Language – Introduction

0 0


lightning-talk-golang

Lightning Talk - Introduction to Go programming language

On Github purplecode / lightning-talk-golang

Go Programming Language

Introduction

https://blog.golang.org/gopher
@source:  www.modulecounts.com

Go (Golang)

  • open source programming language
  • created at Google (2007, Robert Griesemer, Rob Pike, and Ken Thompson)
  • compiled, statically typed
  • garbage collection, structural typing
  • CSP-style* concurrent programming features
* communicating sequential processes

Naming dispute

Go  vs  Go!

Hello World

package main

import "fmt"

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

Tooling

  • go get - simple package manager
  • go test
  • go build
  • go clean
  • go run
  • gofmt - formatter
  • golint - linter
  • godoc - documentation
  • go vet - static analyzer

Pros & Sugar

  • fast compilation time
  • garbage collection
  • initialization through type inference (x := 0 not int x = 0;)
  • built-in concurrency primitives: light-weight processes (goroutines), channels, and the select statement
  • multiple return values, (result, err) pair as convention

Cons*

  • lack of mature libraries
  • no compile-time generics (code duplication)
  • no language extensibility (like operator overloading)
  • overhead of garbage collection
  • no inheritance
  • no assertions
  • no pointer arithmetic
  • no implicit type conversions (by compiler)

Companies using

  • Docker
  • Ethereum
  • Google
  • Dropbox
  • CloudFlare
  • SoundCloud
  • Cloud Foundry
  • CoreOS
  • Couchbase
  • MongoDB
  • Uber
@source:  https://en.wikipedia.org/wiki/Go_(programming_language)

Types

  • byte, int64, float32, etc.
  • boolean
  • string (immutable)
  • arrays
  • hash tables
  • channels
  • pointers
  • custom types (struct)
    type Circle struct {
        radius float64
    }
    
    type ipv4addr uint32
    

Functions

func addFactory(valueToAdd int) func(int) {
    return func(value int) {
        fmt.Println("%d + %d  = %d", value, valueToAdd, value + valueToAdd)
        return value + valueToAdd
    }
}

Interfaces

type geometry interface {
    area() float64
}

type rect struct {
    width, height float64
}

type circle struct {
    radius float64
}

func (r rect) area() float64 {
    return r.width * r.height
}

func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}
func measure(g geometry) {
    fmt.Println(g.area())
}

func main() {
    r := rect{width: 3, height: 4}
    c := circle{radius: 5}
    measure(r)
    measure(c)
}









Composition

type Person struct {
    name string
    age  int
}

func (p Person ) hello() {
    fmt.Printf("Hi, I am %s. I am %d.\n", p.name, p.age)
}

type PersonWithPhone struct {
    Person
    number int
}

func main() {
    a := Person{name: "Alice", age: 12}
    a.hello()

    b := PersonWithPhone{Person{"Bob", 15}, 123456}
    b.age += 10
    b.hello()
}

Concurrency: goroutines

  • primary concurrency construct, a type of light-weight process
  • language specification does not specify how goroutines should be implemented
  • like threads, but cheaper (smaller stacks)
  • current implementations: multiplex goroutines onto a smaller set of operating system threads

Concurrency: channels

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}
@source: https://tour.golang.org/concurrency/6

Defer

func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }

    defer src.Close()
    dst, err := os.Create(dstName)
    if err != nil {
        return
    }

    defer dst.Close()
    return io.Copy(dst, src)
}
@source: https://blog.golang.org/defer-panic-and-recover

Defer

func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
} // 0
func b() {
    for i := 0; i < 4; i++ {
        defer fmt.Print(i)
    }
} // "3210":
func c() (i int) {
    defer func() {
        i++
    }()
    return 1
} // 2
@source: https://blog.golang.org/defer-panic-and-recover

Panic & recover

func main() {
    f()
    fmt.Println("Returned normally from f.")
}

func f() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered in f", r)
        }
    }()
    fmt.Println("Calling g.")
    g(0)
    fmt.Println("Returned normally from g.")
}

func g(i int) {
    if i > 3 {
        fmt.Println("Panicking!")
        panic(fmt.Sprintf("%v", i))
    }
    defer fmt.Println("Defer in g", i)
    fmt.Println("Printing in g", i)
    g(i + 1)
}
Calling g.
Printing in g 0
Printing in g 1
Printing in g 2
Printing in g 3
Panicking!
Defer in g 3
Defer in g 2
Defer in g 1
Defer in g 0
Recovered in f 4
Returned normally from f.













@source: https://blog.golang.org/defer-panic-and-recover

Packages

  • each package has a path ("compress/bzip2", "golang.org/x/net/html") and a name (e.g., bzip2 or html)
  • references to other packages' must always be prefixed with the other package's name
  • package exposes only the capitalized names (io.Reader is public, bzip2.reader is not)
  • package paths often look like partial GitHub urls for compatibility (github.com/gorilla/mux)

Project structure

export GOPATH=$HOME/work
export PATH=$PATH:$GOPATH/bin

bin/
    hello                           # command executable
pkg/
    linux_amd64/
        github.com/golang/example/
            stringutil.a            # package object
src/
        github.com/golang/example/
            .git/                   # repository metadata
            hello/
                hello.go            # command source
            stringutil/
                reverse.go          # package source
                reverse_test.go     # test source

Go package management

Repeatable builds Isolated environments Community consensus https://github.com/golang/go/wiki/PackageManagementToolshttp://jbeckwith.com/2015/05/29/dependency-management-go/

Testing

func TestTimeConsuming(t *testing.T) {
    if testing.Short() {
        t.Skip("skipping test in short mode.")
    }
    //
    t.Fail()
    //
    t.Error("I'm in a bad mood.")
}

Live demo

https://github.com/docker/docker

This is all for now...

Thanks!