5. Quais (grandes) problemas?
❏ Tanto hardware quanto software são gigantes
❏ Milhões de linhas de código
❏ Servidores principalmente em C++ e uma grande
quantidade em Java e Python
❏ Milhares de desenvolvedores trabalhando
❏ Softwares sendo executado em zilhões de maquinas
❏ Sistemas distribuídos em larga escala
6. Software em larga escala
❏ Builds lentos
❏ Dependências não controladas
❏ Custo de updates
❏ Dificuldade para automatizar tarefas
❏ Builds entre várias linguagens de programação
❏ Código difícil de compreender
7. No geral, o desenvolvimento no
é grande, lento, e muitas vezes
desajeitado. Mas é efetivo
''
''
https://talks.golang.org/2012/splash.article
8. ❏ Ken Thompson (B, C, Unix, UTF-8)
❏ Rob Pike (Unix, UTF-8)
❏ Robert Griesemer (Hotspot, JVM)
… e muitos outros engenheiros do Google
9. Muitas pessoas ajudam
a transformar o
protótipo em realidade
Go se tornou um
projeto Open
Source
https://golang.org/doc/faq#history
2008 2009 20102007
Começa a ter
adoção por outros
desenvolvedores
Iniciado e desenvolvido
por Robert Griesemer,
Rob Pike e Ken Thompson
em um projeto part-time
História
13. ❏ Eliminar lentidão
❏ Melhorar a eficacia
❏ Aumentar a produtividade
❏ Manutenção escalável
Go foi projetado para que pessoas possam escrever,
ler, debugar e manter grandes sistemas de software.
O proposito do Go não é ser uma pesquisa sobre
design de linguagens de programação.
O objetivo do Go é fazer com que os programadores
vivam melhor.
Por que usar Go?
15. fix, fmt, get, install, list, tool,
version, vet.
build compila pacotes e dependencias
run compila e executa programas Go
clean remove arquivos objeto
env imprime informações do ambiente
test testa pacotes e benchmarks
Go contém um conjunto de ferramentas
para gerir código fonte...
Principais ferramentas:
Outras ferramentas:
18. ❏ Compilado
❏ Memoria gerenciada (garbage-collected)
❏ Tem seu próprio runtime
❏ Sintaxe simples
❏ Excelente biblioteca padrão
❏ Multi plataforma
❏ Orientação a Objetos
❏ Estaticamente e fortemente tipado
❏ Concorrência (goroutines)
❏ Dependências explicitas
❏ Retorno multi valorado
❏ Ponteiros
e mais...
O que você vai ver em Go
19. Estas características não foram
implementadas em favor da
eficiência e simplicidade
❏ Tratamento de exceções
❏ Herança
❏ Generics
❏ Assert
❏ Sobrecarga de métodos
O que você não vai
ver em Go
21. Pacotes
❏ Todo programa Go é composto por pacotes
❏ Programas começam com o pacote main
❏ Este exemplo usa os pacotes ftm e math
$ go run packages.go
My favorite number is 1
22. ❏ A instrução var declara uma lista de variavéis
❏ O tipo é informado no fim
❏ A instrução var pode incluir inicialização, 1 por variavél. Neste
caso, o tipo pode ser omitido porque será inferido
Variavéis
$ go run variables.go
0 false false false
$ go run variables-with-initiali
1 2 true false no!
23. ❏ Dentro de uma função, pode ser usada a instrução :
= para inicializar e declarar a variavél
Declaração de Variáveis
$ go run short-variable-declarations.go
1 2 3 true false no!
24. $ go run constants.go
Hello world! Happy 3.14 Day! Go rules?
true
❏ Constantes são declaradas com a keyword const
❏ Não é possível usar :=
Constantes
25. Funções
❏ Funções podem ter argumentos
❏ O tipo fica após o nome do argumento
$ go run functions.go
55
26. ❏ Uma função pode ter múltiplos retornos
Retorno de valores múltiplos
$ go run multiple-results.go
world hello
27. ❏ A única estrutura do laço que o Go tem é for
❏ Muito similar com Java ou C, exceto pelos ( )
❏ A parte inicial e final da declaração podem estar vazias
Laço For
$ go run for.go
45
$ go run for-continu
1024
28. $ go run for-is-go-while.go
1024
❏ Ponto e vírgula pode ser removidos para simular um while
❏ for pode executar para "sempre"
Laço while
$ go run forever.go
process took too long
29. ❏ Muito similar com Java ou C, exceto pelos ( )
Condicional
$ go run if.go
1.4142135623730951 2i
30. $ go run switch.go
Go runs on nacl.
❏ Muito similar com Java ou C, exceto pelos ( )
Switch
31. $ go run defer.go
hello world
Defer
❏ A declaração defer adia a execução de uma função até o final do
retorno da função
❏ Os argumentos das chamadas adiadas são avaliados imediatamente
33. Orientação a Objetos
type retangulo struct {
largura, altura int
}
Estruturas do Go (similares a classes)
34. Orientação a Objetos
type retangulo struct {
largura, altura int
}
Go suporta métodos definidos em tipos struct
func (r retangulo) area() int {
return r.largura * r.altura
}
Estruturas do Go (similares a classes)
35. Orientação a Objetos
type retangulo struct {
largura, altura int
}
Go suporta métodos definidos em tipos struct
func (r retangulo) area() int {
return r.largura * r.altura
}
Estruturas do Go (similares a classes)
retangulo{10, 20}
retangulo{largura: 10, altura: 20}
Inicialização de estruturas
36. Orientação a Objetos
package vingadores
type vingador struct {
nome string
}
func NewVingador(nome string) *vingador {
v := new(vingador)
v.nome = nome
return v
}
func main() {
capitao := vingadores.NewVingador("Capitão América")
fmt.Println(capitao.nome)
}
Construtores
37. Orientação a Objetos
package vingadores
type vingador struct {
nome string
}
func NewVingador(nome string) *vingador {
v := new(vingador)
v.nome = nome
return v
}
func main() {
capitao := vingadores.NewVingador("Capitão América")
fmt.Println(capitao.nome)
}
Construtores ❏ Depois de importar um pacote, você pode
consultar os nomes que exporta
❏ Um nome é exportado se começa com
uma LETRA MAIÚSCULA
38. Orientação a Objetos
struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import "fmt"
type pessoa struct {
nome string
idade int
}
func main() {
fmt.Println(pessoa{"Homem de Ferro", 40})
fmt.Println(pessoa{nome: "Thor", idade: 100})
s := pessoa{nome: "Hulk", idade: 45}
fmt.Println(s.nome)
s.idade = 42
fmt.Println(s.idade)
}
39. Orientação a Objetos
struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import "fmt"
type pessoa struct {
nome string
idade int
}
func main() {
fmt.Println(pessoa{"Homem de Ferro", 40})
fmt.Println(pessoa{nome: "Thor", idade: 100})
s := pessoa{nome: "Hulk", idade: 45}
fmt.Println(s.nome)
s.idade = 51
fmt.Println(s.idade)
}
$ go run struct.go
{Homem de Ferro 40}
{Thor 100}
Hulk
42
46. Por que usamos herança?
❏ Reuso de código
Existe efeito colateral em seu uso?
Herança
47. Por que usamos herança?
❏ Reuso de código
Existe efeito colateral em seu uso?
Acoplamos a implementação da classe mãe
muito precocemente. A classe filha precisa
conhecer muito bem o código interno da mãe.
Quebra de encapsulamento
Herança
50. Alguns críticos afirmam que ela nunca
deveria ser utilizada
Go não tem Herança !
Mas tem composição !
Um dos princípios do livro "Design Patterns":
Evite herança, favoreça composição
Herança
57. Herança (anonymous field)
anonymous-field.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import "fmt"
type Cozinha struct {
lampadas int
}
type Quarto struct {
lampadas int
}
type Casa struct {
Cozinha
Quarto
}
func (c Casa) lampadas() int {
return c.Cozinha.lampadas + c.Quarto.lampadas
}
func main() {
c := Casa{Cozinha{2}, Quarto{3}}
fmt.Println("A casa tem ", c.lampadas(), " lampadas")
}
58. Herança (anonymous field)
anonymous-field.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import "fmt"
type Cozinha struct {
lampadas int
}
type Quarto struct {
lampadas int
}
type Casa struct {
Cozinha
Quarto
}
func (c Casa) lampadas() int {
return c.Cozinha.lampadas + c.Quarto.lampadas
}
func main() {
c := Casa{Cozinha{2}, Quarto{3}}
fmt.Println("A casa tem ", c.lampadas(), " lampadas")
}
$ go run anonymous-field.go
A casa tem 5 lampadas
60. Assinatura da função:
func Open(name string) (file *File, err error)
Exemplo de uso com tratamento de erro:
f, err := os.Open("filename.ext")
if err != nil {
log.Fatal(err)
}
// faça algo com o arquivo f
Estados inconsistentes ou anormais são indicados através
do error. Por exemplo a função os.Open
Tratamento de Erros
61. Todo erro em Go é representado pela interface error
type error interface {
Error() string
}
A implementação mais comum é a errorString.
type errorString struct {
s string
}
func (e *errorString) Error() string {
return e.s
}
Representação do erro
62. A forma mais simples de criar um errorString é a partir
da função errors.New
func New(text string) error {
return &errorString{text}
}
Usando a função para disparar um erro:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("negative number")
}
// implementaçào caso f >= 0
}
Disparando um errorString
63. Usando a função para disparar um erro:
func Sqrt(f float64) (float64, error) {
if f < 0 {
return 0, errors.New("negative number")
}
// implementaçào caso f >= 0
}
A forma mais simples de criar um errorString é a partir
da função errors.New
func New(text string) error {
return &errorString{text}
}
Disparando um errorString
Não estamos informando qual o número passado para a
função. Informação muito importante sendo perdida!
64. De forma similar como disparamos um errorString
através da função errors.New
... podemos usar a função Errorf do pacote fmt para
disparar erros mais completos.
Internamente a função Errorf se utiliza da função
errors.New
Disparando erros com Errorf
if f < 0 {
return 0, fmt.Errof("negative number %g", f)
}
65. Esta é uma abordagem muito mais sofisticada do que usar
apenas errorString pois permite type assertions.
type NegativeSqrtError float64
func (f NegativeSqrtError) Error() string {
return fmt.Sprintf("negative number %g",
float64(f))
}
É possível criar suas próprias implementações de erros.
Como por exemplo deste caso do número negativo,
poderíamos por exemplo:
Customizando seus erros
66. tratamento de erros é importante!
As convenções e design da linguagem nos encorajam a
verificar explicitamente por erros onde eles possam ocorrer
indo em desencontro com muitas outras linguagens.
Em alguns casos, isto pode fazer Go um tanto verbosa,
mas felizmente existem técnicas para lidar com isso.
68. Concorrência & Paralelismo
O mundo moderno é paralelo
❏ Multicore
❏ Networks
❏ Cloud Computing
❏ Grande quantidade de usuários.
69. Go suporta concorrência
❏ execução concorrente (goroutines)
❏ sincronização e mensagens (channels)
❏ controle concorrente (select)
70. Concorrência é legal !
Uhu paralelismo !
Isso é uma falacia!
Quando o Go anunciou, muitos ficaram
confusos com a distinção
71. ❏ A concorrência é sobre como lidar com um monte de
coisas ao mesmo tempo.
❏ O paralelismo é sobre fazer muitas coisas ao mesmo
tempo.
❏ A concorrência é sobre a estrutura, o paralelismo é
sobre a execução.
❏ Concorrência fornece uma maneira de estruturar uma
solução para resolver um problema que pode (mas não
necessariamente) ser paralelizável.
Concorrência versus Paralelismo
74. Concorrência versus Paralelismo
❏ Vai ir mais rápido, mas haverá gargalos na pilha e no
incinerador
❏ Precisa sincronizar os Gophers
❏ Comunicação entre os esquilos sera necessária
75. Concorrência versus Paralelismo
❏ Remover os gargalos torna realmente independente
❏ Vai consumir duas vezes mais rápido
❏ Concorrência de dois processos Gopher
76. Concorrência versus Paralelismo
❏ Três Gophers em ação, mas com atrasos prováveis
❏ Cada Gopher é um processo independente, acrescido de
coordenação (comunicação)
77. Concorrência versus Paralelismo
❏ Quatro Gophers em ação, cada com uma tarefa simples
❏ Quatro vezes mais rápido que a versão original com um
78. Concorrência versus Paralelismo
Procedimentos concorrentes
Para cada Gopher um procedimento distinto:
❏ Carregar o carrinho com livros
❏ Mover o carrinho para incinerador
❏ Descarregar o carrinho no incinerador
❏ Retornar o carrinho vazio
Diferentes designs concorrentes permitem diferentes
formas de paralelizar
85. Concorrência versus Paralelismo
❏ Há muitas maneiras de dividir o processamento
❏ Isso é design concorrente
❏ Uma vez que temos a divisão, a paralelização fica mais
fácil
86. É uma função que executa no mesmo
endereço de outras goroutines
❏ Como uma chamada de função no shell com &
Goroutines
88. Apesar de serem parecidas com threads, elas
são muito mais baratas
❏ Goroutines são multiplexados em threads no S.O.
conforme necessário
❏ Quando uma goroutine fica bloqueada, aquela thread
fica bloqueada, mas não impacta em nenhuma outra
goroutine
Goroutines não são threads
89. ❏ Channels são canais que conectam goroutines
concorrentes. Você pode enviar valores para os
canais de uma goroutine e receber esses valores em
outra goroutine
❏ Cria um novo canal com make(chan tipo-val)
❏ A sintaxe <- server para enviar ou receber
mensagens
Channels
90. Channels
channels.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
$ go run channels.go
17 -5 12
92. ❏ Por padrão canais são não buferizados. Só aceitarão
envios se houver um receptor pronto para receber o
valor
❏ Canais buferizados aceitam um número limitado de
valores sem um receptor correspondente para esses
valores
Buffered Channels
95. ❏ Para executar uma goroutine: go
❏ Para enviar ou receber informações entre goroutines:
channels
❏ Use a variável de ambiente GOMAXPROCS para
definir a quantidade de threads
Concorrência em Go
99. Só isso ou tem mais?
❏ Pointer
❏ Struct
❏ Matrix
❏ Slice
❏ Range
❏ Map
❏ Value function
❏ Closures
❏ Method
❏ Interface
❏ Stringer
❏ Error
e muito mais!!!
http://go-tour-br.appspot.com
100. $ go run http.go
Servidor Web
❏ Um servidor web com menos de 15 lines!!