jdd2014: go! the one language you have to try in 2014 - andrzej grzesik
DESCRIPTION
You live and breathe http. Most of the things you do with a computer involve it. How many tiny little http-related utils have you already created? Is it time to stop? By no means, we all do it. I'd just like to encourage you to write the next one in Go. It's a fun little language, which feels like a cross-breed between C (pointers!) and ruby (concise, powerful syntax). But how much? Why, yet another language, but my perl/python/.. does all the things? Well, it does. But go has a few things that make it super sweet, is web-scale and real fun to use!TRANSCRIPT
golangthe one language you have to try in 2014
golangthe one language you have to try in 2014
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
FASTand 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()!}
goroutineslightweight 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
channelschannel := make(chan int)!
unbuffered channels
• sync
• will wait when empty
buffered channelschannel := make(chan int, size)!
buffered channels
• async
• return 0 element when empty
• will only wait when full
basicschannel := 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!