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

Something about Golang

Something about Golang

1bc80e2eee2adeaa8bb577798d92e9d0?s=128

Anton Arhipov

September 30, 2015
Tweet

Transcript

  1. #golang

  2. Pascal C/Asm Perl Java Evolution of a software developer PaintGo

  3. A little bit of history… 2007 2009 2012 2013 2015

    The beginning Open sourced 1.0 1.1 1.5
  4. Where used? https://github.com/golang/go/wiki/GoUsers Google, Docker, Heroku, Cloud Foundry, CoreOS, InfluxDB,

    Dropbox, OpenShift, SoundCloud, Toggl, etc. In the clouds!
  5. “Can't reach the pedals. no brakes. gaining speed. eyes bulging

    in horror. technical debt crash eminent. “ — Tim Dysinger, @dysinger
  6. 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.”
  7. “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
  8. Tour of Go tour.golang.org

  9. package  main   import  "fmt"   func  main()  {  

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

      fmt.Println("Hello,  Devclub!")   }   Java-developers reaction to the capital letter in a function name
  11. None
  12. None
  13. None
  14. None
  15. None
  16. Missing stuff No classes No generics No inheritance No method

    overriding No exceptions etc
  17. No generics? No exceptions? Wut!?

  18. Features Functions Structures Interfaces Methods Slices Pointers Go-routines Channels

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

     2))   }   func  add(a  int,  b  int)  int  {     return  a  +  b   } Functions
  20. func  main()  {     fmt.Println("1  +  2  =",  add(1,

     2))   }   func  add(a  int,  b  int)  int  {     return  a  +  b   } Functions
  21. func  main()  {     fmt.Println("1  +  2  =",  add(1,

     2))   }   func  add(a,  b  int)  int  {     return  a  +  b   } Functions
  22. 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
  23. 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
  24. 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
  25. func  main()  {      double  :=  func(a  int)  int

     {            return  a  *  2      }     double(14)   }   Functions as values
  26. func  main()  {      double  :=  factory()    

    double(14)   }   func  factory()  func(a  int)  int  {      return  func(a  int)  int  {            return  a  *  2      }   } Functions as values
  27. Arrays var  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"}
  28. Slices a  :=  []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]
  29. 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)     }
  30. 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!?
  31. 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
  32. Pointers var  p  *int   i  :=  42   p

     =  &i     fmt.Println(*p)   *p  =  21   fmt.Println(i) 42 21
  33. Pointers var  p  *int   i  :=  42   p

     =  &i     fmt.Println(*p)   *p  =  21   fmt.Println(i)
  34. Pointers var  p  *int   i  :=  42   p

     =  &i     fmt.Println(*p)   *p  =  21   fmt.Println(i) No pointer arithmetics
  35. Structures type  Vertex  struct  {      X  int  

       Y  int   }  
  36. Structures type  Vertex  struct  {      X  int  

       Y  int   }   func  main()  {      fmt.Println(Vertex{1,  2})   }
  37. Methods type  Vertex  struct  {      X  int  

       Y  int   }   func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y   }
  38. Methods type  Vertex  struct  {      X  int  

       Y  int   }   func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y   } v  :=  Vertex{1,  2}   v.Total()
  39. Interfaces type  Entity  interface  {      Total()  int  

    }  
  40. Interfaces type  Entity  interface  {      Total()  int  

    }   Vertex implements Entity func  (v  Vertex)  Total()  int  {      return  v.X  +  v.Y   }
  41. Interfaces v  :=  Vertex  {1,  2}   blah(v) func  blah(e

     Entity)  {        e.Total()   }
  42. Interfaces func  foo(x  interface{})  int  {        x.(Vertex).Total()

      }
  43. 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})
  44. A programmer had a problem. He thought to solve it

    with threads. two Now problems. he has
  45. Go-routines foo(Vertex2{1,2}) go  foo(Vertex2{1,2}) Usual function call Function call in

    a go-routine
  46. 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
  47. Channels ci  :=  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
  48. 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   }
  49. 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   }
  50. 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
  51. 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
  52. 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
  53. 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!
  54. None
  55. Environment https://golang.org/doc/code.html#Workspaces

  56. Environment

  57. Environment

  58. Tooling • go (version, build, test, get, install, …) •

    gofmt • godoc • Editors (vim, atom, IntelliJ IDEA, Sublime Text)
  59. My choice

  60. 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
  61. 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
  62. Testing package  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")     }   }  
  63. Testing package  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
  64. 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 :)
  65. 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
  66. 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?
  67. 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
  68. Resources http://www.miek.nl/downloads/Go/Learning-Go-latest.pdf https://tour.golang.org http://blog.golang.org https://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:
  69. @antonarhipov http://www.slideshare.net/arhan https://speakerdeck.com/antonarhipov