A Linguagem de Programação Go

55
A linguagem de programação Go Francisco Souza Dev in Cachu 2013

description

Palestra "A Linguagem de Programação Go", apresentada no Dev in Cachu 2013, no dia 04 de maio de 2013.

Transcript of A Linguagem de Programação Go

Page 1: A Linguagem de Programação Go

A linguagem de programação GoFrancisco SouzaDev in Cachu 2013

Page 2: A Linguagem de Programação Go

program main

print *, "Hello world!"

end program

Page 3: A Linguagem de Programação Go

what the f**rancisco?!

open source fanboy

Desenvolvedor na Globo.com

Usa Go diaramente para construir o Tsuru

tsuru.io (http://tsuru.io)

Page 4: A Linguagem de Programação Go

Go?

Uma linguagem focada em algumas características...

Eficiência

Segurança

Concorrência

Escalabilidade

Um mascote legal :)

Page 5: A Linguagem de Programação Go
Page 6: A Linguagem de Programação Go

Por que uma nova linguagem?

Page 7: A Linguagem de Programação Go

Linguagens estáticas

Page 8: A Linguagem de Programação Go
Page 9: A Linguagem de Programação Go

package main

import "fmt"

func main() { fmt.Println("#devincachu 2013: eu fui! :D")} Run

Page 10: A Linguagem de Programação Go

Tempo de compilação...

Tsuru: 16 mil linhas de código

% time go install ./...2.53 real 3.03 user 0.56 sys

Compilador + biblioteca padrão: 230++ mil linhas de código

% time ./make.bash47.89 real 59.23 user 11.54 sys

Page 11: A Linguagem de Programação Go

Tempo de compilação (cont.)

Page 12: A Linguagem de Programação Go

Linguagens dinâmicas

Page 13: A Linguagem de Programação Go
Page 14: A Linguagem de Programação Go

Go: o melhor dos dois mundos?

Page 15: A Linguagem de Programação Go

Explorando a biblioteca padrão...

package main

import (

"fmt"

"net"

)

func main() {

listen, err := net.Listen("tcp", "127.0.0.1:3000")

if err != nil {

panic(err)

}

defer listen.Close()

for {

conn, err := listen.Accept()

if err != nil {

panic(err)

}

fmt.Fprintln(conn, "Oi pessoal do #devincachu!")

conn.Close()

}

} Run

Page 16: A Linguagem de Programação Go

Um pouco mais amigável...

127.0.0.1:7070/ (http://127.0.0.1:7070/)

package main

import ( "fmt" "net/http")

func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Oi do #devincachu 2013! :)") }) http.ListenAndServe("127.0.0.1:7070", nil)} Run

Page 17: A Linguagem de Programação Go

Aspectos da linguagem

Page 18: A Linguagem de Programação Go

Variáveis

Muitos jeitos de declarar, alguns mais verbosos, outros mais simples...

var name string name = "Francisco" fmt.Println(name)

var name string = "Francisco" fmt.Println(name)

var name = "Francisco" fmt.Println(name)

name := "Francisco" fmt.Println(name)

Page 19: A Linguagem de Programação Go

Declarações

Na linguagem C e maioria de suas derivadas, declarações podem ser lidas em espiral:

Detalhes:

The Clockwise/Spiral Rule (http://c-faq.com/decl/spiral.anderson.html)

Page 20: A Linguagem de Programação Go

Declarações (cont.)

Em Go, as declarações são sempre da esquerda para a direita:

var name string

var name string = "Francisco"

var name = "Francisco"

name := "Francisco"

var f func(fn func(int) int) func(int) int

Page 21: A Linguagem de Programação Go

Loops

for i := 0; i < 10; i++ { fmt.Println(i) }

for { fmt.Println("Looping forever") break // not really }

Page 22: A Linguagem de Programação Go

Slices & arrays

Em Go, arrays são como os arrays estáticos em C:

var numeros [16]int

Além dos arrays, existem os slices:

var numeros []int

Page 23: A Linguagem de Programação Go

Slices: exemplo

func Reverse(values []int) []int { result := make([]int, len(values)) length := len(values) for i := range values { result[i] = values[length-1-i] } return result}

func main() { numbers := [8]int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(Reverse(numbers[:]))} Run

Page 24: A Linguagem de Programação Go

Funções

func sum(x int, y int) int { return x + y}

func swap(x, y int) (int, int) { return y, x}

func split(sum int) (x, y int) { x = sum * 4 / 9 y = sum - x return}

fmt.Println(sum(10, 5)) fmt.Println(swap(10, 5)) fmt.Println(split(20)) Run

Page 25: A Linguagem de Programação Go

Tipos

type Person struct { Name string Birth time.Time}

type MyString string

type MyInt int

No pacote :

type Duration int64

Page 26: A Linguagem de Programação Go

"Construtores"

Em Go, não existem construtores propriamente ditos, mas há uma convenção na comunidade para construtores ( ):

func NewPerson(name string, birth time.Time) (*Person, error) {

if time.Now().Sub(birth) < 0 {

return nil, errors.New("LOLWUT, did you born in the future?!")

}

person := Person{Name: name, Birth: birth}

return &person, nil

}

Page 27: A Linguagem de Programação Go

Métodos

type Person struct {

Name string

Birth time.Time

}

func (p *Person) Age() int {

difference := time.Now().Sub(p.Birth)

return int(difference / (365 * 24 * time.Hour))

}

p, err := NewPerson("Francisco", date)

if err != nil {

panic(err)

}

fmt.Printf("%s is %d years old.\n", p.Name, p.Age()) Run

Page 28: A Linguagem de Programação Go

Métodos (cont.)

type MyInt int

func (i MyInt) String() string { return fmt.Sprintf("%d", i)}

Page 29: A Linguagem de Programação Go

Interfaces

Page 30: A Linguagem de Programação Go

Interfaces

Go possui interfaces, de forma semelhante à linguagem Java.

type Reader interface { Read(content []byte) (int, error)}

Você pode declarar funções baseadas nessas interfaces:

func Dump(r Reader) { var buf [512]byte n, _ := r.Read(buf[:]) for n > 0 { fmt.Printf("%s", buf) n, _ = r.Read(buf[:]) }}

Page 31: A Linguagem de Programação Go

Interfaces (cont.)

Em , qualquer tipo que tenha o método especificado por uma interface, automaticamente implementa aquela interface, de forma implícita.

Assim, qualquer tipo com o método implementa a interface declarada no slide anterior.

resp, err := http.Get("http://golang.org/")

if err != nil {

panic(err)

}

Dump(resp.Body)

file, err := os.Open("/etc/passwd")

if err != nil {

panic(err)

}

Dump(file)

file.Close()

Page 32: A Linguagem de Programação Go

Tratamento de erros

Page 33: A Linguagem de Programação Go

Lidando com erros

No construtor do tipo , o segundo retorno é do tipo .

func NewPerson(name string, birth time.Time) (*Person, error) {

Page 34: A Linguagem de Programação Go

Lidando com erros (cont.)

Go não inclui o mecanismo de exceções de linguagens como Python e Java. Ao invés disso, a linguagem utiliza o tipo para representar falhas.

Um idioma comum:

func fazAlgumaCoisa() (*Result, error)

Tratando erros:

result, err := fazAlgumaCoisa()if err != nil { panic(err)}

Ignorando erros:

result, _ := fazAlgumaCoisa()

Page 35: A Linguagem de Programação Go

Concorrência

Page 36: A Linguagem de Programação Go

CSP

O modelo de concorrência é inspirado no CSP (Communicating Sequential Processes).

PROC producer (CHAN INT out!) out ! 42:

PROC consumer (CHAN INT in?) INT v: SEQ in ? v:

Page 37: A Linguagem de Programação Go

CSP (cont.)

O modelo também inspirou outras linguagens, como Occam, Erlang e Limbo.

O modelo também está disponível em outras linguagens:

python-csp (https://github.com/python-concurrency/python-csp)

JCSP (http://www.cs.kent.ac.uk/projects/ofa/jcsp/)

Page 38: A Linguagem de Programação Go

CSP em Go

Processos -> goroutines

Canais -> canais :-)

Page 39: A Linguagem de Programação Go

Goroutines

A criação de uma goroutine é uma simples chamada de função precedida pela palavra-chave go.

package main

import "fmt"

func say(what, who string) {

fmt.Printf("%s, %s!\n", what, who)

}

func main() {

say("Hello world", "#devincachu")

} Run

Page 40: A Linguagem de Programação Go

Canais

Em Go, diferentes goroutines se comunicam através de canais.

func sum(values []int, result chan int) { var sum int for _, v := range values { sum += v } result <- sum}

func main() { ch := make(chan int) values := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} go sum(values, ch) fmt.Println(<-ch)} Run

Page 41: A Linguagem de Programação Go

Um exemplo

func elevator(people chan string) { for person := range people { fmt.Printf("Carrying %s...\n", person) time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond) }}

ch := make(chan string) go elevator(ch) for _, p := range people { ch <- p } Run

Page 42: A Linguagem de Programação Go

Concorrência vs Paralelismo

Page 43: A Linguagem de Programação Go

Concorrência vs Paralelismo

Concorrência: lidar com múltiplas coisas ao mesmo tempo

Paralelismo: fazer múltiplas coisas ao mesmo tempo

func elevator(people chan string) { for person := range people { fmt.Printf("Carrying %s...\n", person) time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond) }}

ch := make(chan string) go elevator(ch) for _, p := range people { ch <- p } Run

Page 44: A Linguagem de Programação Go

Hands on

Page 45: A Linguagem de Programação Go

Download de arquivos

O exemplo visa demonstrar um client que baixa arquivos do site textfiles.com.

Page 46: A Linguagem de Programação Go

Download de arquivos (cont.)

Uso do programa:

% ./download -h -d="": Destination directory (where to save files) -u="": URL to download files from -w=2: Number of workers

Exemplo de uso:

% ./download -d files -u http://www.textfiles.com/programming/ -w 50

Page 47: A Linguagem de Programação Go

Solução

Cada worker é uma goroutine, que receberá um canal de arquivos para baixar.

func download(files <-chan string, wg *sync.WaitGroup) {

O é um mecanismo de sincronização que permitirá esperar até que o

worker termine a execução.

Page 48: A Linguagem de Programação Go

Solução (cont.)

Os workers receberão os arquivos a partir de um canal. Haverá um enviando os links através desse canal.

func extract(url string, files chan<- string) error {

O extrator utilizará uma expressão regular para extrair os arquivos.

var link = regexp.MustCompile(`<a href="([\w-]+\.txt)">[\w-]+\.txt</a>`)

Page 49: A Linguagem de Programação Go

Declaração das flags

Go tem um pacote na biblioteca padrão para declaração de flags a serem utilizadas na linha de comando.

var url, dstdir stringvar workers uint

func init() { flag.StringVar(&url, "u", "", "URL to download files from") flag.StringVar(&dstdir, "d", "", "Destination directory (where to save files)") flag.UintVar(&workers, "w", 2, "Number of workers")}

A função init é executada sempre que o pacote é importado. No caso do pacote main, a função é executada antes da função .

Page 50: A Linguagem de Programação Go

Extrator

func extract(url string, files chan<- string) error { resp, err := http.Get(url) if err != nil { return err } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { return err } links := link.FindAllSubmatch(bytes.ToLower(b), -1) for _, l := range links { files <- string(l[1]) } close(files) return nil}

Page 51: A Linguagem de Programação Go

Worker

func download(files <-chan string, wg *sync.WaitGroup) { defer wg.Done() for file := range files { resp, err := http.Get(url + file) if err != nil { log.Printf("Failed to download %q: %s.", file, err) continue } p := path.Join(dstdir, file) f, err := os.Create(p) if err != nil { log.Printf("Failed to open %q: %s.", p, err) continue } _, err = io.Copy(f, resp.Body) resp.Body.Close() f.Close() if err != nil { log.Printf("Failed to write %q: %s.", p, err) } }}

Page 52: A Linguagem de Programação Go

Juntando todo mundo

func main() { flag.Parse() os.MkdirAll(dstdir, 0755) var wg sync.WaitGroup if workers < 1 { workers = 2 } files := make(chan string, workers) for i := uint(0); i < workers; i++ { wg.Add(1) go download(files, &wg) } err := extract(url, files) if err != nil { log.Fatal(err) } wg.Wait()}

Page 53: A Linguagem de Programação Go

Demonstração

Page 54: A Linguagem de Programação Go

Próximos passos

Site da linguagem

golang.org (http://golang.org)

A Tour of Go

tour.golang.org (http://tour.golang.org)

Effective Go

golang.org/doc/effective_go.html (http://golang.org/doc/effective_go.html)

Communicating Sequential Processes

www.usingcsp.com (http://www.usingcsp.com)

Códigos da palestra

github.com/fsouza/go-devincachu (https://github.com/fsouza/go-devincachu)

Page 55: A Linguagem de Programação Go

Thank you

Francisco SouzaDev in Cachu 2013@franciscosouza (http://twitter.com/franciscosouza)

[email protected] (mailto:[email protected])

http://f.souza.cc (http://f.souza.cc)