Go ahead, make my day

Post on 06-May-2015

403 views 0 download

description

An introduction to the go programming language, emphasizing concurrency.

transcript

Go  ahead,  make  my  day.  

Intro  to  Go  programming  language  

Me  @torkale    h8p://github.com/torkale    torkale[at]gmail  

Why  Go?  

Challenge  

Safety  &  Performance   Expressiveness  

&  Convenience  

AL  

Mascot  Performance  Type  safety  Concurrency  Scalability  ProducKvity  

Respected  Parents  

Ken  Thompson  Unix,  B,  UTF-­‐8,  Plan  9      Rob  Pike  Plan  9,  UTF-­‐8,  Limbo,  Unix  team  The  Unix  Programming  Environment  The  PracKce  of  Programming  

History  

Start  Late  2007  

Public    2009  

Go  1.0  March  2012  

Go  1.1  May  2013  

Rob  Pike  Ken  Thompson  

Robert  Griesmer  

Hello  

package  main    import  "fmt"    func  greet()  {  

 fmt.Println("Hello,  I  love  you,  won’t  you  tell  me  your  name?”)  }    func  main()  {  

 greet()  }  

Web  Server  package  main    import  (          "fmt"          "net/h8p"  )    func  handler(w  h8p.ResponseWriter,  r  *h8p.Request)  {          fmt.Fprine(w,  ”Request  from  %s",  r.URL.Path[1:])  }    func  main()  {          h8p.HandleFunc("/",  handler)          h8p.ListenAndServe(":8080",  nil)  }  

BASICS  

Basic  types  DeclaraKons  CondiKons  Loops  Slice  Map  

Basic  Types  bool    string    int    int8    int16    int32    int64  uint  uint8  uint16  uint32  uint64  uintptr    byte  //  alias  for  uint8    rune  //  alias  for  int32            //  represents  a  Unicode  code  point    float32  float64    complex64  complex128  

DeclaraKons  var  i  int  i  =  getInteger()    j  :=  getInteger()    value,  err  :=  getValueOrError()    value2,  _  :=  getValueOrError()  

CondiKons  var  even  bool    if  x%2  ==  0  {          even  =  true  }    if  x%2  ==  0  {          even  =  true  }  else  {          even  =  false  }    if  mod  :=  x%2;  mod  ==  0  {          even  =  true  }  

Loops  factorial  :=  1  for  i  :=  2;  i  <=  num;  i++  {          factorial  *=  i  }    nextPowerOf2  :=  1  for  nextPowerOf2  <  num  {          nextPowerOf2  *=2  }    for  {          //  Forever  }  

Slice  primes  :=  []int{2,  3,  5,  7,  11,  13}    fmt.Println("primes[1:4]  ==",  primes[1:4])    zeroes  :=  make([]int,  5)  fmt.Println("zeroes  ==",  zeroes)    for  i,  v  :=  range  primes  {            fmt.Prine("(%d)  =  %d\n",  i,  v)  }  for  _,  v  :=  range  primes  {            fmt.Prine("%d\n",  v)  }  

Map  m  :=  make(map[string]int)  m["Ten"]  =  10  fmt.Println(m)                                                                                                capitals  :=  map[string]string{      "Jerusalem":  "Israel",      "Paris":  "France",      "London":  "UK",  }  fmt.Println(capitals)                                                                                                delete(capitals,  "London")  v,  present  :=  capitals["London"]  fmt.Println("The  capital:",  v,  "Present?",  present)  

TYPES  

Custom  types  Extension  via  composiKon  Methods  

Custom  Types  type  Name  string    type  Person  struct  {          first  Name          last    Name  }    type  Hero  struct  {          Person          power  string  }    type  Crowd  struct  {          people  []Person  }  

Methods  func  (dude  Person)  FullName()  string  {          return  fmt.Sprine("%s  %s",  dude.first,  dude.last)  }    func  (dude  Person)  SetFirst(name  Name)  {          dude.first  =  name  }    func  (h  *Hero)  ToString()  string  {          return  fmt.Sprine("Name:  %s  Power:  %s",  h.FullName(),  h.power)  }    func  NewPerson(f,  l  Name)  Person  {          return  Person{f,  l}  }  

INTERFACES  

AbstracKon  Duck  typing  Signatures  Implicit  

interfaces  type  Talker  interface  {          Talk()  string  }    func  (dude  Person)  Talk()  string  {          return  fmt.Sprine("My  name  is  %s",  dude.FullName())  }    func  MakeSomeoneTalk(talker  Talker)  string  {          return  talker.Talk()  }    func  interfaces()  {          fmt.Println(MakeSomeoneTalk(NewPerson("Robert",  "de  Niro")))  }  

FUNCTIONS  

Higher-­‐order  funcKons  Custom  funcKon  types  Closures  MulKple  return  values  

FuncKons  type  PersonAcKon  func(some  Person)  Name    func  (crowd  Crowd)  ConcatPersonAcKons(acKon  PersonAcKon)  string  {          var  result  string          for  _,  dude  :=  range  crowd.people  {                  result  =  fmt.Sprine("%s  %s",  result,  acKon(dude))          }          return  result  }    func  AllLastNames(crowd  Crowd)  string  {          return  crowd.ConcatPersonAcKons(func(dude  Person)  Name  {                  return  dude.last          })  }  

defer  func  MeasureStart(label  string)  (string,  Kme.Time)  {          return  label,  Kme.Now()  }    func  Measure(label  string,  startTime  Kme.Time)  {          duraKon  :=  Kme.Now().Sub(startTime)          fmt.Println(label,  "ComputaKon  took",  duraKon)  }    func  benchmark()  {          defer  Measure(MeasureStart("benchmark()"))          Kme.Sleep(Kme.Second)  }  

CONCURRENCY  

CSP  go-­‐rouKne  channels  select  

CommunicaKng  SequenKal  Processes    

“Do  not  communicate  by  sharing  memory;  instead  share  memory  by  communicaKng”  

go  rouKnes  var  a  string    func  Init()  {      a  =  "finally  started"      return  }    func  doSomethingElse()  {      //  …  }    func  Simple()  string{      go  Init()      doSomethingElse()      return  a  }  

tradiKonal  var  (      a  string      wg  sync.WaitGroup  )    func  Init()  {      defer  wg.Done()      a  =  "finally  started"  }    func  Simple()  string{      wg.Add(1)      go  Init()      wg.Wait()      //  do  something  else      return  a  }  

channel  package  channel    var  (      a  string      ready  chan  bool  )    func  Init()  {      a  =  "finally  started"      ready  <-­‐  true  }    func  Simple()  string{      ready  =  make(chan  bool)      go  Init()        //  do  something  else      <-­‐ready      return  a  }  

Producer  /  Consumer  func  producer(c  chan  string){      defer  close(c)      for  {          work  :=  getWork()          c  <-­‐  work      }  }      func  consumer(c  chan  string)  {      for  msg  :=  range  c  {              process(msg)      }  }    func  ProducerConsumer()  {      c  :=  make(chan  string)      go  producer(c)      consumer(c)  }  

Producer  /  Consumer  func  producer(c  chan  string){      defer  close(c)      for  {          work  :=  getWork()          c  <-­‐  work      }  }      func  consumer(c  chan  string,  abort  <-­‐chan  Kme.Time)  {      for  {          select  {          case  msg  :=  <-­‐c:              process(msg)          case  <-­‐  abort:              return          }      }  }    func  ProducerConsumer()  {      c  :=  make(chan  string)      go  producer(c)            abort  :=  Kme.A|er(2*Kme.Second)      consumer(c,  abort)  }  

Barber  Shop  Var        seats  =  make(chan  Customer,  2)      customers  :=  []Customer{  "Al",  "Bob",  "Chad",  "Dave"  }  )    func  barber()  {      for  {          c  :=  <-­‐seats          fmt.Println("Barber  shaving",  c)      }  }    func  (c  Customer)  enter()  {      select  {      case  seats  <-­‐  c:      default:          fmt.Println("Customer",  c,  "Leaves")      }  }    func  BarberShop()  {      go  barber()      for  _,  c  :=  range  customers  {          go  c.enter()      }  }  

GO  COMMAND  

version  build  test  get  

install    fmt  …  build  -­‐-­‐race  (1.1+)  

h8p://golang.org/  h8p://tour.golang.org/  h8ps://code.google.com/p/go-­‐wiki/wiki/Projects  h8ps://groups.google.com/forum/#!forum/golang-­‐nuts  #go-­‐nuts  on  irc.freenode.net  h8ps://www.facebook.com/groups/golanggonuts