golang 
the one language you have to try in 2014
golang 
the one language you have to try in 2014
Andrzej Grzesik 
! 
! 
! 
@ags313 
andrzej@grzesik.it 
andrzejgrzesik.info
about:me
dev going deeper
disclaimers
my opinions are my own
I hate computers
questions? 
shoot!
golang
gopher
free and open source
BSD licensed
comes from G
FAST 
and I mean FAST
tl;dr; 
C++ and ruby had a wild time
play with it tonight
so, why do I like go?
no runtime dependencies!
more pleasant than C
go toolchain
go command
most important thing
there is only one formatting
package main! 
! 
import "fmt"! 
! 
func main() {! 
!fmt.Println("Hello world")! 
}!
types
types 
• uint8, uint16, uint32, uint64 
• int8, int16, int32, int64 
• float32, float64 
• complex64, complex128 
• byte alias for uint8 
• rune alias for int32 
• string
func program() {! 
var text! 
text = “zomg"! 
more := "zomg"! 
! 
fmt.Println(len(text));! 
}!
maps
func main() {! 
attendees := map[string]bool{! 
"Phil": true,! 
"Marcin": true,! 
}! 
! 
fmt.Println(attendees["Phil"]) // true! 
fmt.Println(attendees["ags"]) // false! 
partygoers["ags"] = true! 
fmt.Println(attendees["ags"]) // true! 
}!
structs
type Rectangle struct {! 
a, b int32! 
}! 
! 
func main() {! 
var rect Rectangle! 
rect = Rectangle{5, 10}! 
rect = Rectangle{a: 10, b: 5}! 
! 
HasArea(s).Area()! 
}
type Square struct {! 
side int32! 
}! 
! 
func (sq Square) Area() int32 {! 
return sq.side * sq.side! 
}! 
! 
func main() {! 
s := Square{16}! 
area := s.Area()! 
}
interfaces
type Square struct {! 
side int32! 
}! 
! 
func (sq Square) Area() int32 {! 
return sq.side * sq.side! 
}! 
! 
type HasArea interface {! 
Area() int32! 
}! 
! 
func main() {! 
s := Square{16}! 
HasArea(s).Area()! 
}
goroutines 
lightweight threads
func f(i int) {! 
amt := rand.Intn(1000)! 
time.Sleep(time.Duration(amt) * time.Millisecond)! 
fmt.Println(i)! 
}! 
! 
func main() {! 
for i := 0; i < 3; i++ {! 
go f(i)! 
}! 
var input string! 
fmt.Scanln(&input)! 
}
how many will run? 
runtime.GOMAXPROCS(4)
channels
channels 
• communicate between funcs 
• typed 
• thread-safe
channels 
channel := make(chan int)!
unbuffered channels 
• sync 
• will wait when empty
buffered channels 
channel := make(chan int, size)!
buffered channels 
• async 
• return 0 element when empty 
• will only wait when full
basics 
channel := make(chan int)! 
c <- a! 
! 
<- c! 
! 
a = <- c! 
! 
a, ok = <- c!
func program() {! 
channel := make(chan int) ! 
}! 
! 
func from(connection chan int) {! 
connection <- rand.Intn(255)! 
}! 
! 
func to(connection chan int) {! 
i := <- connection! 
fmt.Println(“much received", i)! 
}!
but that’s not cool yet
coordinate routines
func program() {! 
channel := make(chan int) ! 
! 
go func() {! 
close(channel)! 
// or! 
channel <- anything! 
}()! 
! 
<- channel! 
}!
func program() {! 
latch := make(chan int) ! 
! 
go worker()! 
close(latch)! 
}! 
! 
func worker() {! 
<- latch ! 
}!
generators
id := make(chan int64)! 
go func() {! 
var counter int64 = 0! 
for {! 
id <- counter! 
counter += 1! 
} ! 
}()
multiple channels at once!
func program() {! 
select {! 
case a := <- channel! 
! 
case b, mkay := other! 
! 
case output <- z! 
! 
default:! 
}! 
}!
ranges
func fillIn(channel chan int) {! 
channel <- 1! 
channel <- 2! 
channel <- 4! 
close(channel)! 
}! 
! 
func main() {! 
channel := make(chan int)! 
go fillIn(channel)! 
! 
for s := range channel {! 
fmt.Printf("%d n", s)! 
}! 
}
packages
[18:48][agrzesik@melmac:~/vcs/talks/go/hello]! 
$ find .! 
.! 
./bin! 
./bin/main! 
./pkg! 
./pkg/darwin_amd64! 
./pkg/darwin_amd64/hello.a! 
./src! 
./src/hello! 
./src/hello/hello.go! 
./src/main! 
./src/main/.main.go.swp! 
./src/main/main.go!
import (! 
"code.google.com/p/go.net/websocket"! 
"fmt"! 
"net/http"! 
)!
go get
net
echo server
const listenAddr = "localhost:4000"! 
! 
func main() {! 
l, err := net.Listen("tcp", listenAddr)! 
if err != nil {! 
log.Fatal(err)! 
}! 
for {! 
c, err := l.Accept()! 
if err != nil {! 
log.Fatal(err)! 
}! 
io.Copy(c, c)! 
}! 
}
concurrent echo server
const listenAddr = "localhost:4000"! 
! 
func main() {! 
l, err := net.Listen("tcp", listenAddr)! 
if err != nil {! 
log.Fatal(err)! 
}! 
for {! 
c, err := l.Accept()! 
if err != nil {! 
log.Fatal(err)! 
}! 
go io.Copy(c, c)! 
}! 
}
const listenAddr = "localhost:4000"! 
! 
func main() {! 
l, err := net.Listen("tcp", listenAddr)! 
if err != nil {! 
log.Fatal(err)! 
}! 
for {! 
c, err := l.Accept()! 
if err != nil {! 
log.Fatal(err)! 
}! 
io.Copy(c, c)! 
}! 
}
websockets?
func main() {! 
http.Handle("/", websocket.Handler(handler))! 
http.ListenAndServe("localhost:1984", nil)! 
}! 
! 
func handler(c *websocket.Conn) {! 
var s string! 
fmt.Fscan(c, &s)! 
fmt.Println("Received:", s)! 
fmt.Fprint(c, “hey!”)! 
}!
so, what looks bad?
type AssetMetas struct {! 
! Metas []AssetMeta `json:"assetMetas"`! 
}! 
! 
type AssetMeta struct {! 
! ResourceName string `json:"resource_name"`! 
! Md5 string `json:"md5"`! 
! Urls []string `json:"urls"`! 
}!
so, go code!

Go, the one language to learn in 2014