atmosphere 2014: go, go, go - the one language to try in 2014. (or: "write only an eight of the...
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! Or at least come and listen how did we get rid of 87% of our codebase in a day :-) Andrzej Grzesik - I like programming. I do it a lot, mostly on the JVM, usually writing fancy backends for big, distributed systems. I also display a particular affection to continuous delivery.. UI, unless quickly hacked, is not my play ;-) I believe that most problems we deal with are people problems, so I mix and match tools with technologies to achieve my goals, make people happy and achieve world peace :-) I believe in software quality, and organize GeeCON, Polish JUG, Krakow Software Craftsmanship, Cracow Hadoop User Group. In my free time, I read paper books and cycle, a lot!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!