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

A Linguagem de Programação Go

Embed Size (px)

DESCRIPTION

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

Citation preview

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)