Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Gophers! Go, google's open source language - WX...

Ben Lovell
October 25, 2013

Gophers! Go, google's open source language - WXG Guildford 2013

Go was conceived within Google to scratch their itch for a fully featured systems programming language with a super-fast compiler and runtime performance close to that of the C programming language.

We'll take a high level glance at how Go can help you write performant and maintainable servers and applications, how Go's language-level concurrency constructs "go-routines" and "channels" make traditional multithreading headaches a thing of the past and a brief look into Go's "batteries included" amazing standard library.

Go is built from the ground up for concurrency - a commonly misunderstood term and often used interchangeably with parallelism. We'll talk about this distinction and why it is increasingly significant in the age of multicore and multi-CPU systems and servers.

Of course, Go isn't perfect. I'll take you on a tour of some of Go's controversial design decisions and the reasoning behind them. Hopefully turning the typical and initial reaction - "huh?" into "ah!"

This talk was presented at WXG Guildford. http://wxg.co.uk

Ben Lovell

October 25, 2013
Tweet

More Decks by Ben Lovell

Other Decks in Programming

Transcript

  1. go will be the server language of the future -

    Tobias Lütke, Shopify founder
  2. package main ! import "fmt" ! type Person string !

    func (person Person) Greet() { fmt.Printf("Hello, %s!\n", person) } ! func main() { person := Person("Ben") person.Greet() } !
  3. package main ! import "fmt" ! type Person struct {

    Name string Age int } ! func (person Person) Greet() { fmt.Println(person.Name) } ! func main() { person := Person{"Ben", 33} person.Greet() } !
  4. package person ! import "fmt" ! type Person struct {

    Name string } ! func (person Person) Greet() string { return fmt.Sprintf("Hello, %s", person.Name) } ~/gocode/src/person/person.go
  5. ~/gocode/src/main.go ~/gocode/src % go run main.go package main ! import

    ( "fmt" "person" ) ! func main() { person := person.Person{"Ben"} greeting := person.Greet() fmt.Println(greeting) } !
  6. package main ! import ( "fmt" "strings" ) ! func

    Upcase(name string) { name = strings.ToUpper(name) } ! func main() { name := "ben" Upcase(name) ! fmt.Println(name) } ! // ben
  7. // BEN package main ! import ( "fmt" "strings" )

    ! func Upcase(name *string) { *name = strings.ToUpper(*name) } ! func main() { name := "ben" Upcase(&name) ! fmt.Println(name) } !
  8. package main ! import "fmt" ! type Person struct {

    Name string } ! func (p Person) SetName(name string) { p.Name = name } ! func main() { p := Person{"Ben"} p.SetName("Jim") fmt.Println(p.Name) } ! // Ben
  9. // Jim package main ! import "fmt" ! type Person

    struct { Name string } ! func (p *Person) SetName(name string) { p.Name = name } ! func main() { p := Person{"Ben"} p.SetName("Jim") fmt.Println(p.Name) } !
  10. // I’M BEN // I’m Ben type Person struct {

    Name string } ! func (p Person) Greet() { fmt.Println("I'm", p.Name) } ! type Manager struct { Person } ! func (m Manager) Greet() { fmt.Println("I'M", strings.ToUpper(m.Name)) } ! func main() { m := Manager{Person{"Ben"}} m.Greet() m.Person.Greet() }
  11. type Person struct { Name string } ! func (p

    Person) Greet() { fmt.Println("I'm", p.Name) } ! type Manager struct { Person } ! func (m Manager) Greet() { fmt.Println("I'M", strings.ToUpper(m.Name)) } ! func greet(greeters ...Greeter) { for _, g := range greeters { g.Greet() } } ! type Greeter interface { Greet() } ! func main() { greet(Person{"Ben"}, Manager{Person{"Bob"}}, Person{"Anne"}) }
  12. func greet(greeters ...interface{}) { for _, g := range greeters

    { greetable, ok := g.(Greeter) if ok { greetable.Greet() } else { fmt.Println("Whoops!") } } } ! func main() { greet(Person{"Ben"}, "WHOA!", Person{"Anne"}) } ! // I’m Ben // Whoops! // I’m Anne
  13. // os.Open signature func Open(name string) (file *File, err error)

    ! ! f, err := os.Open("file.txt") if err != nil { log.Fatal(err) } // do something with the open file
  14. f, err := os.Open("file.txt") if err != nil { log.Fatal(err)

    } ! defer f.Close() // do something with the *File f
  15. func main() { go greet() ! // hang around a

    while time.Sleep(2 * time.Second) } ! func greet() { fmt.Println("Hi!") }
  16. //make a channel c := make(chan int) ! //send on

    the channel c <- 1 ! //receive from the channel val := <- c
  17. func ping(c chan string) { for i := 0; ;

    i++ { c <- "ping" } } ! func printer(c chan string) { for { msg := <- c fmt.Println(msg) time.Sleep(time.Second * 1) } } ! func main() { c := make(chan string) ! go ping(c) go printer(c) ! time.Sleep(time.Second * 10) }
  18. func main() { s := make(chan int) ! go greet(s)

    s <- 1 } ! func greet(signaller chan int) { <- signaller fmt.Println("Hi!") }
  19. func main() { functions := make(chan func(int, int)(int)) go executor(functions)

    ! functions <- add functions <- multiply functions <- subtract } ! func add(x, y int) int { return x + y } ! func multiply(x, y int) int { return x * y } ! func subtract(x, y int) int { return x - y } ! func executor(functions chan func(int, int)(int)) { for f := range functions { fmt.Println("The result is: ", f(10, 10)) } }
  20. func main() { functions := make(chan func(int, int)(int)) go executor(functions)

    ! functions <- add functions <- multiply functions <- subtract } ! func add(x, y int) int { return x + y } ! func multiply(x, y int) int { return x * y } ! func subtract(x, y int) int { return x - y } ! func executor(functions chan func(int, int)(int)) { for f := range functions { fmt.Println("The result is: ", f(10, 10)) } } The result is: 20 The result is: 100 The result is: 0
  21. func printer(c chan string, d chan string) { for {

    select { case x := <- c: fmt.Println(x) case y := <- d: fmt.Println(y) case <- time.After(1 * time.Second): fmt.Println("Timeout!") } } } ! func main() { c := make(chan string) d := make(chan string) ! go ping(c) go ping(d) go printer(c, d) ! time.Sleep(time.Second * 10) }