69
#golang

Something about Golang

Embed Size (px)

Citation preview

#golang

Pascal C/Asm Perl Java

Evolution of a software developer

PaintGo

A little bit of history…

2007 2009 2012 2013 2015

The beginning

Open sourced

1.0 1.1 1.5

Where used?

https://github.com/golang/go/wiki/GoUsers

Google, Docker, Heroku, Cloud Foundry, CoreOS, InfluxDB, Dropbox, OpenShift, SoundCloud, Toggl, etc.

In the clouds!

“Can't reach the pedals. no brakes. gaining speed. eyes bulging in horror. technical debt crash eminent. “

— Tim Dysinger, @dysinger

Paul Phillips @extempore2

“go is a terrible, terrible language, yet still a major productivity boost. Amdahl's law in another context.”

“You often see languages which are fighting the last war. Go is fighting the War of 1812.”

“reduce: what you will do with your expectations after you start with Go”

“Rust and Scala drown you in complexity. Go drowns you in simplicity.”

Paul Phillips @extempore2

Tour of Gotour.golang.org

package  main  

import  "fmt"  

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

package  main  

import  "fmt"  

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

Java-developers reaction to the capital letter in a function name

Missing stuffNo classes

No generics

No inheritance

No method overriding

No exceptions

etc

No generics? No exceptions? Wut!?

FeaturesFunctions

Structures

Interfaces

Methods

Slices

Pointers

Go-routines

Channels

func  main()  {     fmt.Println("1  +  2  =",  add(1,  2))  }  

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

Functions

func  main()  {     fmt.Println("1  +  2  =",  add(1,  2))  }  

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

Functions

func  main()  {     fmt.Println("1  +  2  =",  add(1,  2))  }  

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

Functions

func  main()  {      s,  p  :=  calculate(1,  2)     fmt.Printf("1+2=%d,  1*2=%d",  s,  p)  }  

func  calculate(a,  b  int)  (int,  int)  {      return  a  +  b,  a  *  b  }

Functions

func  main()  {      s,  p  :=  calculate(1,  2)     fmt.Printf("1+2=%d,  1*2=%d",  s,  p)  }  

func  calculate(a,  b  int)  (int,  int)  {      return  a  +  b,  a  *  b  }

Functions

func  main()  {      s,  p  :=  calculate(1,  2)     fmt.Printf("1+2=%d,  1*2=%d",  s,  p)  }  

func  calculate(a,  b  int)  (s,  p  int)  {      s  :=  a  +  b      p  :=  a  *  b      return  }

Functions

func  main()  {      double  :=  func(a  int)  int  {            return  a  *  2      }     double(14)  }  

Functions as values

func  main()  {      double  :=  factory()     double(14)  }  

func  factory()  func(a  int)  int  {      return  func(a  int)  int  {            return  a  *  2      }  }

Functions as values

Arraysvar  a  [4]int  a[0]  =  1  i  :=  a[0]

http://blog.golang.org/go-slices-usage-and-internals

arr  :=  [2]string{"Foo",  "Bar"}

arr  :=  […]string{"Foo",  "Bar"}

Slicesa  :=  []int{1,  2,  3}      //  [1  2  3]

No size definition

b  :=  append(a,  4,  5)    //  [1  2  3  4  5]c  :=  make(c,  3)              //  [0  0  0]d  :=  b[1:3]                      //  [2  3]e  :=  b[:3]                        //  [1  2  3]

Maps

  monthdays  :=  map[string]int{       "Jan":  31,  "Feb":  28,  "Mar":  31,       "Apr":  30,  "May":  31,  "Jun":  30,       "Jul":  31,  "Aug":  31,  "Sep":  30,       "Oct":  31,  "Nov":  30,  "Dec":  31,     }  

  for  month,  days  :=  range  monthdays  {       fmt.Println(month,  days)     }

Maps

  monthdays  :=  map[string]int{       "Jan":  31,  "Feb":  28,  "Mar":  31,       "Apr":  30,  "May":  31,  "Jun":  30,       "Jul":  31,  "Aug":  31,  "Sep":  30,       "Oct":  31,  "Nov":  30,  "Dec":  31,     }  

  for  month,  days  :=  range  monthdays  {       fmt.Println(month,  days)     } Obligatory comma!?

Maps

  monthdays  :=  map[string]int{       "Jan":  31,  "Feb":  28,  "Mar":  31,       "Apr":  30,  "May":  31,  "Jun":  30,       "Jul":  31,  "Aug":  31,  "Sep":  30,       "Oct":  31,  "Nov":  30,  "Dec":  31,     }  

  value,  ok  :=  monthdays["Jan"]    fmt.Println(value)    //    31      fmt.Println(ok)          //    true

Pointers

var  p  *int  

i  :=  42  p  =  &i    fmt.Println(*p)  *p  =  21  fmt.Println(i)

42

21

Pointers

var  p  *int  

i  :=  42  p  =  &i    fmt.Println(*p)  *p  =  21  fmt.Println(i)

Pointers

var  p  *int  

i  :=  42  p  =  &i    fmt.Println(*p)  *p  =  21  fmt.Println(i)

No pointer arithmetics

Structurestype  Vertex  struct  {      X  int      Y  int  }  

Structurestype  Vertex  struct  {      X  int      Y  int  }  

func  main()  {      fmt.Println(Vertex{1,  2})  }

Methodstype  Vertex  struct  {      X  int      Y  int  }  

func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y  }

Methodstype  Vertex  struct  {      X  int      Y  int  }  

func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y  }

v  :=  Vertex{1,  2}  v.Total()

Interfaces

type  Entity  interface  {      Total()  int  }  

Interfaces

type  Entity  interface  {      Total()  int  }  

Vertex implements Entity

func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y  }

Interfaces

v  :=  Vertex  {1,  2}  blah(v)

func  blah(e  Entity)  {        e.Total()  }

Interfaces

func  foo(x  interface{})  int  {        x.(Vertex).Total()  }

Interfaces

func  foo(x  interface{})  int  {        x.(Vertex).Total()  }

panic:  interface  conversion:  interface  is  main.Vertex2,  not  main.Vertex  

goroutine  1  [running]:  main.main()     main.go:25  +0xcd  exit  status  2  

foo(Vertex2{1,2})

A programmer had a problem. He thought to solve it with threads.

two Now problems. he has

Go-routines

foo(Vertex2{1,2})

go  foo(Vertex2{1,2})

Usual function call

Function call in a go-routine

func  ready(w  string,  sec  int)  {     time.Sleep(time.Duration(sec)  *  time.Second)     fmt.Println(w,  "is  ready!")  }  

func  main()  {     go  ready("Tea",  2)     go  ready("Coffee",  1)     fmt.Println("I'm  waiting")     time.Sleep(5  *  time.Second)  }

I’m waiting Coffee is ready Tea is ready

Channelsci  :=  make(chan  int)  cs  :=  make(chan  string)  cf  :=  make(chan  interface{})

ci <- 1 ← send value 1 into channel ci i := <-ci ← read int from channel ci

var  c  chan  int  

func  ready(w  string,  sec  int)  {     time.Sleep(time.Duration(sec)  *  time.Second)     fmt.Println(w,  "is  ready!”)      с  <-­‐  1  }  

func  main()  {     go  ready("Tea",  2)     go  ready("Coffee",  1)     fmt.Println("I'm  waiting")      <-­‐c      <-­‐c  }

var  done  =  make(chan  bool)  var  msgs  =  make(chan  int)  

func  produce()  {     for  i  :=  0;  i  <  10;  i++  {       msgs  <-­‐  i     }     done  <-­‐  true  }  

func  consume()  {     for  {       msg  :=  <-­‐msgs       println(msg)     }  }  

func  main()  {     go  produce()     go  consume()     <-­‐  done  }

var  done  =  make(chan  bool)  var  msgs  =  make(chan  int)  

func  produce()  {     for  i  :=  0;  i  <  10;  i++  {       msgs  <-­‐  i     }     done  <-­‐  true  }  

func  consume()  {     for  {       msg  :=  <-­‐msgs       println(msg)     }  }  

func  main()  {     go  produce()     go  consume()     <-­‐  done  }

Start  go-­‐routines

var  done  =  make(chan  bool)  var  msgs  =  make(chan  int)  

func  produce()  {     for  i  :=  0;  i  <  10;  i++  {       msgs  <-­‐  i     }     done  <-­‐  true  }  

func  consume()  {     for  {       msg  :=  <-­‐msgs       println(msg)     }  }  

func  main()  {     go  produce()     go  consume()     <-­‐  done  }

Send  values

var  done  =  make(chan  bool)  var  msgs  =  make(chan  int)  

func  produce()  {     for  i  :=  0;  i  <  10;  i++  {       msgs  <-­‐  i     }     done  <-­‐  true  }  

func  consume()  {     for  {       msg  :=  <-­‐msgs       println(msg)     }  }  

func  main()  {     go  produce()     go  consume()     <-­‐  done  }

Receive  values  and  print

var  done  =  make(chan  bool)  var  msgs  =  make(chan  int)  

func  produce()  {     for  i  :=  0;  i  <  10;  i++  {       msgs  <-­‐  i     }     done  <-­‐  true  }  

func  consume()  {     for  {       msg  :=  <-­‐msgs       println(msg)     }  }  

func  main()  {     go  produce()     go  consume()     <-­‐  done  }

Done!

Environment

https://golang.org/doc/code.html#Workspaces

Environment

Environment

Tooling

• go (version, build, test, get, install, …)

• gofmt

• godoc

• Editors (vim, atom, IntelliJ IDEA, Sublime Text)

My choice

What’s missing?

Debugger IntelliJ IDEA plugin is still in development

Can use GDB, but better do something else instead

Dependency management A lot of different solutions, no de facto standard

-vendor option in 1.5

Cross-compilation

http://dave.cheney.net/2015/03/03/cross-compilation-just-got-a-whole-lot-better-in-go-1-5

env GOOS=linux GOARCH=386 go build hello.go

1. Build on Mac for Linux

2. Run the binary without installing extra dependencies or runtime on Linux host

Testingpackage  math  

func  Add(a,  b  int)  int  {     return  a  +  b  } package  math  

import  "testing"  

func  TestAdd(t  *testing.T){     if  Add(1,  3)  !=  4  {       t.Error("Expecting  4")     }  }  

Testingpackage  math  

func  Add(a,  b  int)  int  {     return  a  +  b  } package  math  

import  "testing"  

func  TestAdd(t  *testing.T){     if  Add(1,  3)  !=  4  {       t.Error("Expecting  4")     }  }  

/usr/local/go/bin/go  test  -­‐v  ./...  -­‐run  ^TestAdd$  Testing  started  at  03:35  ...  ?         _/Users/anton/work-­‐src/mygo   [no  test  files]PASS  ok       _/Users/anton/work-­‐src/mygo/math   0.007s

Q: Can you build the enterprise apps in Go?

And now a million $$ question

https://www.youtube.com/watch?v=cFJkLfujOts Building bank in Go:

A: Apparently, you can :)

Can I haz decimal type?

https://github.com/shopspring/decimal

import  "github.com/shopspring/decimal"  …  x,  _  :=  decimal.NewFromString("0.1")sum  :=  x.Add(x).Add(x) // 0.3

import  (     "net/http"     "fmt"  )  

func  handler(w  http.ResponseWriter,                              r  *http.Request)  {     fmt.Fprintf(w,  "Welcome!")  }  

func  main()  {     http.HandleFunc("/",  handler)     http.ListenAndServe(":8080",  nil)  }

Compare  to  Java?

Frameworks

Gorilla web toolkit http://www.gorillatoolkit.org/

Go-Kit http://gokit.io

List of various frameworks and libraries: https://github.com/avelino/awesome-go

Resourceshttp://www.miek.nl/downloads/Go/Learning-Go-latest.pdfhttps://tour.golang.org

http://blog.golang.orghttps://www.youtube.com/playlist?list=PLMW8Xq7bXrG58Qk-9QSy2HRh2WVeIrs7e

https://www.youtube.com/channel/UCx9QVEApa5BKLw9r8cnOFEA

Gopher Academy:

dotGo:

https://gist.github.com/kachayev/21e7fe149bc5ae0bd878 Channels are not enough:

http://dave.cheney.net/2015/08/08/performance-without-the-event-loop

Performance without event loop:

@antonarhipovhttp://www.slideshare.net/arhan https://speakerdeck.com/antonarhipov