Skip to content

Latest commit

 

History

History
2180 lines (1772 loc) · 86.4 KB

OUTLINE.md

File metadata and controls

2180 lines (1772 loc) · 86.4 KB

Outline

01 – Visão Geral do Curso

Bem-vindo!

  • Bem vindo ao curso!
  • Eu sou...
  • Go foi criada por gente foda que criou o Unix, B, UTF-8...
  • Em 2006 o Google queria...
  • É uma linguagem que vem crescendo horrores...
  • Nesse curso você vai aprender...
  • O curriculum que vamos estudar...
  • Para os novos na programação... Para os programadores experientes...
  • Participe!

Por que Go?

  • Antes de investir seu tempo em aprender a linguagem Go, é bom você entender por que isso é uma boa idéia.
  • O que estava acontecendo no Google...
  • Criada por Ken Thompson (Unix, B, C), Rob Pike (UTF-8), e Robert Griesemer.
  • Em 2006, não tinha uma linguagem de compilação rápida, execução rápida, e fácil de programar. É uma linguagem criada para resolver as questões de performance e complexidade.
  • https://golang.org/doc/faq#creating_a_new_language
  • Eficiente
    • Standard library é déis
    • Multiplataforma.
    • Garbage collection (lightning fast!)
    • Cross-compile.
  • Fácil de usar
    • É uma linguagem compilada, de tipagem forte e estática,
    • Tem pouquíssimas palavras reservadas, que vamos aprender todas no curso, ou seja, é muito de boas de aprender
    • só sobe nas listas de popularidade
  • Killer feature: Em 2006, logo após o primeiro dual core. Thread: 1mb. Goroutine: 2kb.
  • É massa!
  • Quando usar Go?
    • Escala
    • Seviços web, redes, servers (machine learning, image processing, crypto, ...)
    • Quando precisar de uma lingaugem rápida, simples, fácil de aprender, e fácil de usar.
  • Usa em: APIs, CLIs, microservices, libraries/framework, processamento de dados, ... É a base dos serviços de cloud e orquestração de containers.
  • Quem usa? https://github.com/golang/go/wiki/GoUsers
  • Go é OOP? https://golang.org/doc/faq#Is_Go_an_object-oriented_language
  • Mais um: https://golang.org/doc/faq#principles
  • $$$: https://insights.stackoverflow.com/survey/2017#technology-top-paying-technologies-by-region -> US

Sucesso

  • Qual o motivo que algumas pessoa obtem sucesso e outras não?

  • Eu quero que você obtenha sucesso com este curso, então vamos falar sobre o assunto.

  • Perguntaram a Bill Gates e Warren Buffet, independentemente, qual seria sua principal característica responsável pelo seu sucesso. A resposta de ambos foi:

  • Foco.

  • (Fonte: https://www.linkedin.com/pulse/20140707144749-8353952-the-one-word-answer-to-why-bill-gates-and-warren-buffett-have-been-so-successful/)

  • O que isso quer dizer?

  • Escolha um objetivo e se concentre nele. Faça desse objetivo sua maior prioridade.

  • Foco. Concentração. → "Vou conseguir chegar lá ou vou morrer tentando."

  • Exemplo: minha carreira de violinista.

  • Faça disso uma prioridade, não uma resolução de ano novo. Tem vezes que seus amigos vão te chamar pra fazer algo massa e você vai ter que dizer, "gente, não vai dar, estou estudando."

  • O Todd costuma dizer: de gota em gota se enche um balde. A cada dia uma gota. Algumas semanas depois você olha o balde, e pô meu não tem quase nada ali, pra que esse esforço todo? Mas depois de alguns anos o balde vai estar transbordando. É só trabalhar, de gota em gota.

  • Então:

    • Seja proativo.
    • Trabalhe. Invista as horas de esforço.
    • Faça exercício, coma direito, tenha uma atitude positiva.
    • Easy mode: pare de ver TV e use esse tempo pra estudar.
  • E algumas dicas práticas:

    • Metade das pessoas que assiste esse curso diz que eu falo muito rápido. A outra metade diz que eu falo muito devagar. Então use o botãozinho ali no player e selecione a velocidade mais apropriada pra você.
    • Boa parte de qualquer aprendizado se resume a memória muscular. Então quando eu passar exercícios, digite o código. Não copie e cole. Digite. E quando eu estiver programando "ao vivo," não passe pra frente, assista, e preste atenção. Se acostume com o processo, com o ato de programar.
  • Com paciência e com persistência você chega lá.

Recursos

Como esse curso funciona

  • Velocidade de playback.
  • Repetição.
  • Erros.
  • Português vs. inglês
    • Obviamente esse é um curso em português.
    • Mas a língua semi-oficial da programação e do mundo da tecnologia em geral é a língua inglesa.
    • Por isso vamos utilizar bastante termos em inglês ao longo do curso.
    • As explicações serão em português, claro, mas quero que todos fiquem bem confortáveis com os termos em inglês.
    • Desta maneira você será auto-suficiente e poderá procurar por documentação e ajuda por toda a internet, não somente nos sites em português.
    • (Alem de que eu não sei e nem quero saber o nome em português de boa parte dessas coisas :P)
  • Constantemente "em progresso."
  • Seu feedback é super importante!

Work in progress!

  • Em construção!

02 – Variáveis, Valores & Tipos

Go Playground

  • É online, funciona sem instalar nem configurar nada.
  • Assim você pode começar a programar o mais rápido possível.
  • Mais pra frente no curso vou explicar direitinho como configurar tudo no seu computador.
  • Go Playground.
    • Função share. Use para compartilhar código, por exemplo pra fazer uma pergunta em um fórum.
    • Função imports.
    • Função format.
      • Maneira idiomática: a gente fala da mesma maneira que a comunidade onde estamos.
    • Função run.

Hello world!

  • Estrutura básica:
    • package main.
    • func main: é aqui que tudo começa, é aqui que tudo acaba.
    • import.
  • Packages:
    • Pacotes são coleções de funções pré-prontas (ou não) que você pode utilizar.
    • Notação: pacote.Identificador. Exemplo: fmt.Println()
    • Documentação: fmt.Println.
  • Variáveis: "uma variável é um objeto (uma posição na memória) capaz de reter e representar um valor ou expressão."
  • Variáveis não utilizadas? Não pode: _ nelas.
  • ...funções variádicas.
  • Lição principal: package main, func main, pacote.Identificador.

Operador curto de declaração

  • := parece uma marmota (gopher) ou o punisher.
  • Uso:
    • Tipagem automática
    • Só pode repetir se houverem variáveis novas
    • != do assignment operator (operador de atribuição)
    • Só funciona dentro de codeblocks
  • Terminologia:
    • keywords (palavras-chave) são termos reservados
    • operadores, operandos
    • statement (declaração, afirmação) → uma linha de código, uma instrução que forma uma ação, formada de expressões
    • expressão -> qualquer coisa que "produz um resultado"
    • scope (abrangência)
      • package-level scope
  • Lição principal:
    • := utilizado pra criar novas variáveis, dentro de code blocks
    • = para atribuir valores a variáveis já existentes

A palavra-chave var

  • Variável declarada em um code block é undefined em outro
  • Para variáveis com uma abrangência maior, package level scope, utilizamos var
  • Funciona em qualquer lugar
  • Prestar atenção: chaves, colchetes, parênteses

Explorando tipos

  • Tipos em Go são extremamente importantes. (Veremos mais quando chegarmos em métodos e interfaces.)
  • Tipos em Go são estáticos.
  • Ao declarar uma variável para conter valores de um certo tipo, essa variável só poderá conter valores desse tipo.
  • O tipo pode ser deduzido pelo compilador:
    • x := 10
    • var y = "a tia do batima"
  • Ou pode ser declarado especificamente:
    • var w string = "isso é uma string"
    • var z int = 15
    • na declaração var z int com package scope, atribuição z = 15 no codeblock (somente)
  • Tipos de dados primitivos: disponíveis na linguagem nativamente como blocos básicos de construção
    • int, string, bool
  • Tipos de dados compostos: são tipos compostos de tipos primitivos, e criados pelo usuário
    • slice, array, struct, map
  • O ato de definir, criar, estruturar tipos compostos chama-se composição. Veremos muito disso futuramente.

Valor zero

  • Declaração vs. inicialização vs. atribuição de valor. Variáveis: caixas postais.
  • O que é valor zero?
  • Os zeros:
    • ints: 0
    • floats: 0.0
    • booleans: false
    • strings: ""
    • pointers, functions, interfaces, slices, channels, maps: nil
  • Use := sempre que possível.
  • Use var para package-level scope.

O pacote fmt

  • Setup: strings, ints, bools.
  • Strings: interpreted string literals vs. raw string literals.
    • Rune literals.
    • Em ciência da computação, um literal é uma notação para representar um valor fixo no código fonte.
  • Format printing: documentação.
    • Grupo #1: Print -> standard out
      • func Print(a ...interface{}) (n int, err error)
      • func Println(a ...interface{}) (n int, err error)
      • func Printf(format string, a ...interface{}) (n int, err error)
        • Format verbs. (%v %T)
    • Grupo #2: Print -> string, pode ser usado como variável
      • func Sprint(a ...interface{}) string
      • func Sprintf(format string, a ...interface{}) string
      • func Sprintln(a ...interface{}) string
    • Grupo #3: Print -> file, writer interface, e.g. arquivo ou resposta de servidor
      • func Fprint(w io.Writer, a ...interface{}) (n int, err error)
      • func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
      • func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

Criando seu próprio tipo

  • Revisando: tipos em Go são extremamente importantes. (Veremos mais quando chegarmos em métodos e interfaces.)
  • Tem uma história que Bill Kennedy dizia que se um dia fizesse uma tattoo, ela diria "type is life."
  • Grande parte dos aspectos mais avançados de Go dependem quase que exclusivamente de tipos.
  • Como fundação para estas ferramentas, vamos aprender a declarar nossos próprios tipos.
  • Revisando: tipos são fixos. Uma vez declarada uma variável como de um certo tipo, isso é imutável.
  • type hotdog int → var b hotdog (main hotdog)
  • Uma variável de tipo hotdog não pode ser atribuida com o valor de uma variável tipo int, mesmo que este seja o tipo subjacente de hotdog.

Conversão, não coerção

  • Conversão de tipos é o que soa.
  • Em Go não se diz casting, se diz conversion.
  • a = int(b)
  • ref/spec#Conversions
  • Fim da sessão. Parabéns! Dicas, motivação e exercícios.

03 – Exercícios: Ninja Nível 1

Contribua seu código

  • Nesse curso a gente vai fazer um monte de exercícios.
    • Talvez você queira contribuir suas próprias soluções.
    • Talvez você tenha exemplos melhores que os que estamos mostrando aqui.
  • Para compartilhar me manda o link no twitter do seu código no Go Playground, twitter.com/ellenkorbes!
  • "@ellenkorbes Olha essa solução pro exercício Ninja nível 5, exercício 2: O que vc acha?"

Na prática: exercício #1

  • Esses são seus primeiros exercícios, e seus primeiros passos.

  • Completando os exercícios dessa seção, você será um ninja nível 1.

  • É o seu primeiro passo pra se tornar um developer ninja.

  • Esses exercícios servem pra reforçar seu aprendizado. Só se aprende a programar programando. Ninguem aprende a andar de bicicleta assistindo vídeos de pessoas andando de bicicleta. É necessário botar a mão na massa.

  • Eu vou começar explicando qual é o exercício. Aí vou pedir pra você dar pausa. Esse é o momento de por os miolos pra trabalhar, encontrar sua solução, tec-tec-tec, e rodar pra ver se funciona. Depois é só dar play novamente, ver a minha abordagem para a mesma questão, e comparar nossas soluções.

  • Vamos lá:

  • Utilizando o operador curto de declaração, atribua estes valores às variáveis com os identificadores "x", "y", e "z".

    1. 42
    2. "James Bond"
    3. true
  • Agora demonstre os valores nestas variáveis, com:

    1. Uma única declaração print
    2. Múltiplas declarações print
  • Solução: https://play.golang.org/p/yYXnWXIQNa

Na prática: exercício #2

  • Use var para declarar três variáveis. Elas devem ter package-level scope. Não atribua valores a estas variáveis. Utilize os seguintes identificadores e tipos para estas variáveis:
    1. Identificador "x" deverá ter tipo int
    2. Identificador "y" deverá ter tipo string
    3. Identificador "z" deverá ter tipo bool
  • Na função main:
    1. Demonstre os valores de cada identificador
    2. O compilador atribuiu valores para essas variáveis. Como esses valores se chamam?
  • Solução: https://play.golang.org/p/pAFd-F7uGZ

Na prática: exercício #3

  • Utilizando a solução do exercício anterior:
    1. Em package-level scope, atribua os seguintes valores às variáveis:
      1. para "x" atribua 42
      2. para "y" atribua "James Bond"
      3. para "z" atribua true
    2. Na função main:
      1. Use fmt.Sprintf para atribuir todos esses valores a uma única variável. Faça essa atribuição de tipo string a uma variável de nome "s" utilizando o operador curto de declaração.
      2. Demonstre a variável "s".
  • Solução: https://play.golang.org/p/QFctSQB_h3

Na prática: exercício #4

  • Crie um tipo. O tipo subjacente deve ser int.
  • Crie uma variável para este tipo, com o identificador "x", utilizando a palavra-chave var.
  • Na função main:
    1. Demonstre o valor da variável "x"
    2. Demonstre o tipo da variável "x"
    3. Atribua 42 à variável "x" utilizando o operador "="
    4. Demonstre o valor da variável "x"
  • Para os aventureiros: https://golang.org/ref/spec#Types
  • Agora já somos quase ninjas nível 1!
  • Solução: https://play.golang.org/p/snm4WuuYmG

Na prática: exercício #5

  • Utilizando a solução do exercício anterior:
    1. Em package-level scope, utilizando a palavra-chave var, crie uma variável com o identificador "y". O tipo desta variável deve ser o tipo subjacente do tipo que você criou no exercício anterior.
    2. Na função main:
      1. Isto já deve estar feito:
        1. Demonstre o valor da variável "x"
        2. Demonstre o tipo da variável "x"
        3. Atribua 42 à variável "x" utilizando o operador "="
        4. Demonstre o valor da variável "x"
      2. Agora faça tambem:
        1. Utilize conversão para transformar o tipo do valor da variável "x" em seu tipo subjacente e, utilizando o operador "=", atribua o valor de "x" a "y"
        2. Demonstre o valor de "y"
        3. Demonstre o tipo de "y"
  • Solução: https://play.golang.org/p/uq81T_fasP

Na prática: exercício #6

  • Prova!
  • Link: https://goo.gl/forms/s9y91iVSPvA4iahj1
  • Se você deu pausa e fez todos os exercícios anteriores você mesmo, e só viu a resposta depois... e se você der pausa agora e fizer a prova inteira por conta própria, e só assistir as respostas depois... sabe o que isso quer dizer? Que você é ninja. Ninja nível 1. Tá no caminho certo pra ser um developer ninja mestre.

04 – Fundamentos da Programação

Tipo booleano

  • Agora vamos explorar os tipos de maneira mais detalhada. golang.org/ref/spec. A começar pelo bool.
  • O tipo bool é um tipo binário, que só pode conter um dos dois valores: true e false. (Verdadeiro ou falso, sim ou não, zero ou um, etc.)
  • Sempre que você ver operadores relacionais (==, <=, >=, !=, <, >), o resultado da expressão será um valor booleano.
  • Booleans são fundamentais nas tomadas de decisões em lógica condicional, declarações switch, declarações if, fluxo de controle, etc.
  • Na prática:
    • Zero value
    • Atribuindo um valor
    • Bool como resultado de operadores relacionais
  • Go Playground: https://play.golang.org/p/7joj615nZw

Como os computadores funcionam

Tipos numéricos

  • int vs. float: Números inteiros vs. números com frações.
  • golang.org/ref/spec → numeric types
  • Integers:
    • Números inteiros
    • int & uint → “implementation-specific sizes”
    • Todos os tipos numéricos são distintos, exceto:
      • byte = uint8
      • rune = int32 (UTF8) (O código fonte da linguagem Go é sempre em UTF-8).
    • Tipos são únicos
      • Go é uma linguagem estática
      • int e int32 não são a mesma coisa
      • Para "misturá-los" é necessário conversão
    • Regra geral: use somente int
  • Floating point:
    • Números racionais ou reais
    • Regra geral: use somente float64
  • Na prática:
  • “implementation-specific sizes”? Runtime package. Word.

Overflow

  • Um uint16, por exemplo, vai de 0 a 65535.
  • Que acontece se a gente tentar usar 65536?
  • Ou se a gente estiver em 65535 e tentar adicionar mais 1?
  • Playground: https://play.golang.org/p/t7Z4m127F2t

Tipo string (cadeias de caracteres)

Sistemas numéricos

Constantes

  • São valores imutáveis.
  • Podem ser tipadas ou não:
    • const oi = "Bom dia"
    • const oi string = "Bom dia"
  • As não tipadas só terão um tipo atribuido a elas quando forem usadas.
    • Ex. qual o tipo de 42? int? uint? float64?
    • Ou seja, é uma flexibilidade conveniente.
  • Na prática: int, float, string.
    • const x = y
    • const ( x = y )

Iota

  • golang.org/ref/spec
  • Numa declaração de constantes, o identificador iota representa números sequenciais.
  • Na prática.
    • iota, iota + 1, a = iota b c, reinicia em cada const, _
  • Go Playground: https://play.golang.org/p/eSrwoQjuYR

Deslocamento de bits

05 – Exercícios: Ninja Nível 2

Na prática: exercício #1

Na prática: exercício #2

  • Escreva expressões utilizando os seguintes operadores, e atribua seus valores a variáveis.
    • ==
    • !=
    • <=
    • <
    • =

  • Demonstre estes valores.
  • Solução: https://play.golang.org/p/BMYEch6_s8

Na prática: exercício #3

Na prática: exercício #4

  • Crie um programa que:
    • Atribua um valor int a uma variável
    • Demonstre este valor em decimal, binário e hexadecimal
    • Desloque os bits dessa variável 1 para a esquerda, e atribua o resultado a outra variável
    • Demonstre esta outra variável em decimal, binário e hexadecimal
  • Solução: https://play.golang.org/p/IiwgT0v3Mp

Na prática: exercício #5

Na prática: exercício #6

Na prática: exercício #7

06 – Fluxo de Controle

Entendendo fluxo de controle

  • Computadores lêem programas de uma certa maneira, do mesmo jeito que nós lemos livros, por exemplo, de uma certa maneira.

  • Quando nós ocidentais lemos livros, lemos da frente pra trás, da esquerda pra direito, de cima pra baixo.

  • Computadores lêem de cima pra baixo.

  • Ou seja, sua leitura é sequencial. Isso chama-se fluxo de controle sequencial.

  • Alem do fluxo de controle sequencial, há duas declarações que podem afetar como o computador lê o código:

    • Uma delas é o fluxo de controle de repetição (loop). Nesse caso, o computador vai repetir a leitura de um mesmo código de uma maneira específica. O fluxo de controle de repetição tambem é conhecido como fluxo de controle iterativo.
    • E o outro é o fluxo de controle condicional, ou fluxo de controle de seleção. Nesse caso o computador encontra uma condição e, através de uma declaração if ou switch, toma um curso ou outro dependendo dessa condição.
  • Ou seja, há três tipos de fluxo de controle: sequencial, de repetição e condicional.

  • Nesse capítulo:

    • Sequencial
    • Iterativo (loop)
      • for: inicialização, condição, pós
      • for: hierarquicamente
      • for: condição ("while")
      • for: ...ever?
      • for: break
      • for: continue
    • Condicional
      • declarações switch/case/default
        • não há fall-through por padrão
        • criando fall-through
        • default
        • múltiplos casos
        • casos podem ser expressões
          • se resultarem em true, rodam
        • tipo
      • if
        • bool
        • o operador "!"
        • declaração de inicialização
        • if, else
        • if, else if, else
        • if, else if, else if, ..., else

Loops: inicialização, condição, pós

  • For
    • Inicialização, condição, pós
    • Ponto e vírgula?
    • gobyexample.com
    • Não existe while!

Loops: nested loop (repetição hierárquica)

  • For
    • Repetição hierárquica
    • Exemplos: relógio, calendário

Loops: a declaração for

  • For: inicialização, condição, pós
  • For: condição ("while")
  • For: ...ever? (http servers)
  • For: break
  • golang.org/ref/spec#For_statements, Effective Go
  • (Range vem mais pra frente.)

Loops: break & continue

Loops: utilizando ascii

  • Desafio surpresa!
  • Format printing:
    • Decimal %d
    • Hexadecimal %#x
    • Unicode %#U
    • Tab \t
    • Linha nova \n
  • Faça um loop dos números 33 a 122, e utilize format printing para demonstrá-los como texto/string.
  • Solução: https://play.golang.org/p/REm2WHyzzz

Condicionais: a declaração if

Condicionais: if, else if, else

Condicionais: a declaração switch

  • Switch:
    • pode avaliar uma expressão
      • switch statement == case (value)
      • default switch statement == true (bool)
    • não há fall-through por padrão
    • criando fall-through
    • default
    • cases compostos

Condicionais: a declaração switch pt. 2 & documentação

  • Pode avaliar tipos
  • Pode haver uma expressão de inicialização

Operadores lógicos condicionais

07 – Exercícios: Ninja Nível 3

Na prática: exercício #1

Na prática: exercício #2

  • Põe na tela: O unicode code point de todas as letras maiúsculas do alfabeto, três vezes cada.
  • Por exemplo: 65 U+0041 'A' U+0041 'A' U+0041 'A' 66 U+0042 'B' U+0042 'B' U+0042 'B' ...e por aí vai.
  • Solução: https://play.golang.org/p/QlP6nVchq-

Na prática: exercício #3

Na prática: exercício #4

Na prática: exercício #5

Na prática: exercício #6

Na prática: exercício #7

Na prática: exercício #8

Na prática: exercício #9

  • Crie um programa que utilize a declaração switch, onde o switch statement seja uma variável do tipo string com identificador "esporteFavorito".
  • Solução: https://play.golang.org/p/4-iTPZwfEz

Na prática: exercício #10

  • Anote (à mão) o resultado das expressões:
    • fmt.Println(true && true)
    • fmt.Println(true && false)
    • fmt.Println(true || true)
    • fmt.Println(true || false)
    • fmt.Println(!true)
  • Ninja nível 3! Parabéns!

08 – Agrupamentos de Dados

Array

  • Estruturas de dados, ou agrupamentos de dados, nos permitem agrupar valores diferentes. Estes valores podem ser ou não do mesmo tipo.
  • As estruturas que veremos são: arrays, slices, structs e maps.
  • Vamos começar com arrays. Arrays em Go são uma fundação, e não algo que utilizamos todo dia.
  • Seu tamanho deve estar presente na declaração: var x [n]int
  • Atribui-se valores a suas posições com: x[i] = y (0-based)
  • Para ver o tamanho usa-se: len(x)
  • ref/spec: "The length is part of the array's type" → [5]int != [6]int
  • Effective Go: Arrays são úteis para [umas coisas que a gente não vai fazer nunca] e servem de fundação para slices. Use slices ao invés de arrays.
  • Go Playground: https://play.golang.org/p/Fv-sDF-ryZ

Slice: literal composta

  • O que são tipos de dados compostos?
    • Wikipedia: Composite_data_type
    • Effective Go: Composite literals
    • ref/spec: Composite literals
  • Uma slice agrupa valores de um único tipo.
  • Criando uma slice: literal composta → x := []type{values}
  • Go Playground: https://play.golang.org/p/W7Cxm8NPZC

Slice: for range

Slice: fatiando ou deletando de uma fatia

Slice: anexando a uma slice

  • Effective Go: append (package builtin)
  • x = append(slice, ...values)
  • x = append(slice, slice...)
  • Todd: unfurl → desdobrar, desenrolar
  • Nome oficial: enumeration
  • Go Playground: https://play.golang.org/p/RpkDCTumpT

Slice: make

  • Slices são feitas de arrays.
  • Elas são dinâmicas, podem mudar de tamanho.
  • Sempre que isso acontece, um novo array é criado e os dados são copiados.
  • É conveniente, mas tem um custo computacional.
  • Para otimizar as coisas, podemos utilizar make.
  • make([]T, len, cap)
  • "The length of a slice may be changed as long as it still fits within the limits of the underlying array; just assign it to a slice of itself. The capacity of a slice, accessible by the built-in function cap, reports the maximum length the slice may assume."
  • len(x), cap(x)
  • x[n] onde n > len é out of range. Use append.
  • Append > cap modifica o array subjacente.
  • pkg/builtin/#append: "If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated."
  • Effective Go.
  • Go Playground: https://play.golang.org/p/e8GWzyEEL8

Slice: slice multi-dimensional

Slice: a surpresa do array subjacente

  • Isso tudo aqui a gente já viu:
  • Toda slice tem um array subjacente.
  • Um slice é: um ponteiro/endereço para um array, mais len e cap (que é o len to array).
  • Exemplo:
    • x := []int{...números}
    • y := append(x[:i], x[:i]...)
    • pkg/builtin/#append: "If it has sufficient capacity, the destination is resliced to accommodate the new elements. If it does not, a new underlying array will be allocated."
    • Ou seja, y utiliza o mesmo array subjacente que x.
    • O que nos dá um resultado inesperado.
  • Ou seja, bom saber de antemão pra não ter que aprender na marra.
  • Go Playground: https://play.golang.org/p/BBJLuIjU_i

Maps: introdução

  • Utiliza o formato key:value.
  • E.g. nome e telefone
  • Performance excelente para lookups.
  • map[key]value{ key: value }
  • Acesso: m[key]
  • Key sem value retorna zero. Isso pode trazer problemas.
  • Para verificar: comma ok idiom.
    • v, ok := m[key]
    • ok é um boolean, true/false
  • Na prática: if v, ok := m[key]; ok { }
  • Para adicionar um item: m[v] = value
  • Maps não tem ordem.
  • Go Playground: https://play.golang.org/p/JXDdJan8Ev

Maps: range & deletando

09 – Exercícios: Ninja Nível 4

Na prática: exercício #1

  • Usando uma literal composta:
    • Crie um array que suporte 5 valores to tipo int
    • Atribua valores aos seus índices
  • Utilize range e demonstre os valores do array.
  • Utilizando format printing, demonstre o tipo do array.
  • Solução: https://play.golang.org/p/tpWDzzlO2l

Na prática: exercício #2

  • Usando uma literal composta:
    • Crie uma slice de tipo int
    • Atribua 10 valores a ela
  • Utilize range para demonstrar todos estes valores.
  • E utilize format printing para demonstrar seu tipo.
  • Solução: https://play.golang.org/p/ST3TKusuOd

Na prática: exercício #3

  • Utilizando como base o exercício anterior, utilize slicing para demonstrar os valores:
    • Do primeiro ao terceiro item do slice (incluindo o terceiro item!)
    • Do quinto ao último item do slice (incluindo o último item!)
    • Do segundo ao sétimo item do slice (incluindo o sétimo item!)
    • Do terceiro ao penúltimo item do slice (incluindo o penúltimo item!)
    • Desafio: obtenha o mesmo resultado acima utilizando a função len() para determinar o penúltimo item
  • Solução: https://play.golang.org/p/1aPXVeR1mf

Na prática: exercício #4

  • Começando com a seguinte slice:
    • x := []int{42, 43, 44, 45, 46, 47, 48, 49, 50, 51}
  • Anexe a ela o valor 52;
  • Anexe a ela os valores 53, 54 e 55 utilizando uma única declaração;
  • Demonstre a slice;
  • Anexe a ela a seguinte slice:
    • y := []int{56, 57, 58, 59, 60}
  • Demonstre a slice x.
  • Solução: https://play.golang.org/p/6WNJ0Otpy0

Na prática: exercício #5

  • Comece com essa slice:
    • x := []int{42, 43, 44, 45, 46, 47, 48, 49, 50, 51}
  • Utilizando slicing e append, crie uma slice y que contenha os valores:
    • [42, 43, 44, 48, 49, 50, 51]
  • Solução: https://play.golang.org/p/26bT-UKmJH

Na prática: exercício #6

  • Crie uma slice usando make que possa conter todos os estados do Brasil.
    • Os estados: "Acre", "Alagoas", "Amapá", "Amazonas", "Bahia", "Ceará", "Espírito Santo", "Goiás", "Maranhão", "Mato Grosso", "Mato Grosso do Sul", "Minas Gerais", "Pará", "Paraíba", "Paraná", "Pernambuco", "Piauí", "Rio de Janeiro", "Rio Grande do Norte", "Rio Grande do Sul", "Rondônia", "Roraima", "Santa Catarina", "São Paulo", "Sergipe", "Tocantins"
  • Demonstre o len e cap da slice.
  • Demonstre todos os valores da slice sem utilizar range.
  • Solução: https://play.golang.org/p/cGYBphlyCE

Na prática: exercício #7

  • Crie uma slice contendo slices de strings ([][]string). Atribua valores a este slice multi-dimensional da seguinte maneira:
    • "Nome", "Sobrenome", "Hobby favorito"
  • Inclua dados para 3 pessoas, e utilize range para demonstrar estes dados.
  • Solução: https://play.golang.org/p/Gh81-d5tMi

Na prática: exercício #8

  • Crie um map com key tipo string e value tipo []string.
    • Key deve conter nomes no formato sobrenome_nome
    • Value deve conter os hobbies favoritos da pessoa
  • Demonstre todos esses valores e seus índices.
  • Solução: https://play.golang.org/p/nD3TW8VQmH

Na prática: exercício #9

Na prática: exercício #10

  • Utilizando o exercício anterior, remova uma entrada do map e demonstre o map inteiro utilizando range.
  • Solução:

10 – Structs

Struct

  • Struct é um tipo de dados composto que nos permite armazenar valores de tipos diferentes.
  • Seu nome vem de "structure," ou estrutura.
  • Declaração: type x struct { y: z }
  • Acesso: x.y
  • Exemplo: nome, idade, fumante.
  • Go Playground: https://play.golang.org/p/5i0DqxuBp1

Structs embutidos

  • Structs dentro de structs dentro de structs.
  • Exemplo: um corredor de fórmula 1 é uma pessoa (nome, sobrenome, idade) e tambem um competidor (nome, equipe, pontos).
  • Go Playground:

Lendo a documentação

  • É importante se familiarizar com a documentação da linguagem Go.
  • Neste vídeo vamos ver um pouco sobre o que a documentação diz sobre structs.
  • Veremos:
    • ref/spec
      • Já vimos mais da metade dos tipos em Go!
      • Struct types.
        • x, y int
        • anonymous fields
        • promoted fields
  • Go Playground: https://play.golang.org/p/z9UQej4IQT

Structs anônimos

Colocando ordem na casa

  • [???]
  • Go Playground:

11 – Exercícios: Ninja Nível 5

Na prática: exercício #1

  • Crie um tipo "pessoa" com tipo subjacente struct, que possa conter os seguintes campos:
    • Nome
    • Sobrenome
    • Sabores favoritos de sorvete
  • Crie dois valores do tipo "pessoa" e demonstre estes valores, utilizando range na slice que contem os sabores de sorvete.
  • Solução: https://play.golang.org/p/Pyp7vmTJfY

Na prática: exercício #2

  • Utilizando a solução anterior, coloque os valores do tipo "pessoa" num map, utilizando os sobrenomes como key.
  • Demonstre os valores do map utilizando range.
  • Os diferentes sabores devem ser demonstrados utilizando outro range, dentro do range anterior.
  • Solução: https://play.golang.org/p/GLK11Q1_x8y

Na prática: exercício #3

  • Crie um novo tipo: veículo
    • O tipo subjacente deve ser struct
    • Deve conter os campos: portas, cor
  • Crie dois novos tipos: caminhonete e sedan
    • Os tipos subjacentes devem ser struct
    • Ambos devem conter "veículo" como struct embutido
    • O tipo caminhonete deve conter um campo bool chamado "traçãoNasQuatro"
    • O tipo sedan deve conter um campo bool chamado "modeloLuxo"
  • Usando os structs veículo, caminhonete e sedan:
    • Usando composite literal, crie um valor de tipo caminhonete e dê valores a seus campos
    • Usando composite literal, crie um valor de tipo sedan e dê valores a seus campos
  • Demonstre estes valores.
  • Demonstre um único campo de cada um dos dois.
  • Solução: https://play.golang.org/p/3eoGb0kxzT

Na prática: exercício #4

12 – Funções

Sintaxe

Desenrolando (enumerando) uma slice

Defer

  • Funções são ótimas pois tornam nosso código modular. Podemos alterar partes do nosso programa sem afetar o resto!
  • Uma declaração defer chama uma função cuja execução ocorrerá no momento em que a função da qual ela faz parte finalizar.
  • Essa finalização pode ocorrer devido a um return, ao fim do code block da função, ou no caso de pânico em uma goroutine correspondente.
  • "Deixa pra última hora!"
  • ref/spec
  • Sempre usamos para fechar um arquivo após abri-lo.
  • Go Playground: https://play.golang.org/p/sFj8arw0E_

Métodos

  • Um método é uma função anexada a um tipo.
  • Quando se anexa uma função a um tipo, ela se torna um método desse tipo.
  • Pode-se anexar uma função a um tipo utilizando seu receiver.
  • Utilização: valor.método()
  • Exemplo: o tipo "pessoa" pode ter um método oibomdia()
  • Go Playground: https://play.golang.org/p/tQtoqUBpY5

Interfaces & polimorfismo

  • Em Go, valores podem ter mais que um tipo.

  • Uma interface permite que um valor tenha mais que um tipo.

  • Declaração: keyword identifier type → type x interface

  • Após declarar a interface, deve-se definir os métodos necessários para implementar essa interface.

  • Se um tipo possuir todos os métodos necessários (que, no caso da interface{}, pode ser nenhum) então esse tipo implicitamente implementa a interface.

  • Esse tipo será o seu tipo e também o tipo da interface.

  • Exemplos:

    • Os tipos profissão1 e profissão2 contem o tipo pessoa
    • Cada um tem seu método oibomdia(), e podem dar oi utilizando pessoa.oibomdia()
    • Implementam a interface gente
    • Ambos podem acessar o função serhumano() que chama o método oibomdia() de cada gente
    • Tambem podemos no método serhumano() tomar ações diferentes dependendo do tipo: switch pessoa.(type) { case profissão1: fmt.Println(h.(profissão1).valorquesóexisteemprofissão1) [...] }*
    • Go Playground pré-pronto: https://play.golang.org/p/VLbo_1uE-U https://play.golang.org/p/zGKr7cvTPF
    • Go Playground ao vivo: https://play.golang.org/p/njiKbTT20Cr
  • Onde se utiliza?

    • Área de formas geométricas (gobyexample.com)
    • Sort
    • DB
    • Writer interface: arquivos locais, http request/response
  • Se isso estiver complicado, não se desespere. É foda mesmo. Com tempo e prática a fluência vem.

Funções anônimas

  • Anonymous self-executing functions → Funções anônimas auto-executáveis.
  • func(p params) { ... }()
  • Vamos ver bastante quando falarmos de goroutines.
  • Go Playground: https://play.golang.org/p/Rnqmo6X6jh

Func como expressão

Retornando uma função

  • Pode-se usar uma função como retorno de uma função
  • Declaração: func f() return
  • Exemplo: func f() func() int { [...]; return func() int{ return [int] } }
    • ????: fmt.Println(f()())
  • Go Playground: https://play.golang.org/p/zPjoWNrCJF

Callback

  • Primeiro veja se você entende isso: https://play.golang.org/p/QkAtwMZU-z
  • Callback é passar uma função como argumento.
  • Exemplo:
    • Criando uma função que toma uma função e um []int, e usa somente os números pares como argumentos para a função.
    • Go Playground:
  • Desafio: Crie uma função no programa acima que utilize somente os números ímpares.
  • Solução:

Closure

  • Closure é cercar ou capturar um scope para que possamos utilizá-lo em outro contexto. Já vimos:
    • Package-level scope
    • Function-level scope
    • Code-block-in-code-block scope
  • Exemplo de closure:
    • func i() func() int { x := 0; return func() int { x++; return x } }
    • Quando fizermos a := i() teremos um scope, um valor para x.
    • Quando fizermos b := i() teremos outro scope, e x terá um valor independente do x acima.
  • Closures nos permitem salvar dados entre function calls e ao mesmo tempo isolar estes dados do resto do código.
  • Go Playground: https://play.golang.org/p/AdFciYwI2Z

Recursividade

  • WP: "The most common application of recursion is in mathematics and computer science, where a function being defined is applied within its own definition."
  • Exemplos de recursividade: Fractais, matrioscas, efeito Droste (o efeito produzido por uma imagem que aparece dentro dela própria), GNU (“GNU is Not Unix”), etc.
  • No estudo de funções: é uma função que chama a ela própria.
  • Exemplo: fatoriais.

13 – Exercícios: Ninja Nível 6

Na prática: exercício #1

  • Exercício:

    • Crie uma função que retorne um int
    • Crie outra função que retorne um int e uma string
    • Chame as duas funções
    • Demonstre seus resultados
  • Solução: https://play.golang.org/p/rxJM5fgI-9

  • Revisão:

    • Funções!
      • Servem para abstrair código
      • E para reutilizar código
    • A ordem das coisas é:
      • func (receiver) identifier (parameters) (returns) { code }
    • Parâmetros vs. argumentos
    • Funções variádicas
      • Múltiplos parâmetros
      • Múltiplos argumentos
    • Métodos
    • Interfaces & polimorfismo
    • Defer
      • "Deixa pra depois!"
    • Returns
      • Múltiplos returns
      • Returns com nome (blé!)
    • Funcs como expressões
      • Atribuindo uma função a uma variável
    • Callbacks
      • Passando uma função como argumento para outra função
    • Closure
      • Capturando um scope
      • Variáveis declaradas em scopes externos são visíveis em scopes internos
    • Recursividade
      • Uma função que chama a ela mesma
      • Fatoriais

Na prática: exercício #2

  • Crie uma função que receba um parâmetro variádico do tipo int e retorne a soma de todos os ints recebidos;
  • Passe um valor do tipo slice of int como argumento para a função;
  • Crie outra função, esta deve receber um valor do tipo slice of int e retornar a soma de todos os elementos da slice;
  • Passe um valor do tipo slice of int como argumento para a função.
  • Solução: https://play.golang.org/p/Tgv3wwxKV-

Na prática: exercício #3

Na prática: exercício #4

  • Crie um tipo struct "pessoa" que contenha os campos:
    • nome
    • sobrenome
    • idade
  • Crie um método para "pessoa" que demonstre o nome completo e a idade;
  • Crie um valor de tipo "pessoa";
  • Utilize o método criado para demonstrar esse valor.
  • Solução: https://play.golang.org/p/GBZcnu0Ajp

Na prática: exercício #5

  • Crie um tipo "quadrado"
  • Crie um tipo "círculo"
  • Crie um método "área" para cada tipo que calcule e retorne a área da figura
    • Área do círculo: 2 * π * raio
    • Área do quadrado: lado * lado
  • Crie um tipo "figura" que defina como interface qualquer tipo que tiver o método "área"
  • Crie uma função "info" que receba um tipo "figura" e retorne a área da figura
  • Crie um valor de tipo "quadrado"
  • Crie um valor de tipo "círculo"
  • Use a função "info" para demonstrar a área do "quadrado"
  • Use a função "info" para demonstrar a área do "círculo"
  • Solução: https://play.golang.org/p/qLY-q3vffQ

Na prática: exercício #6

Na prática: exercício #7

Na prática: exercício #8

Na prática: exercício #9

Na prática: exercício #10

  • Demonstre o funcionamento de um closure.
  • Ou seja: crie uma função que retorna outra função, onde esta outra função faz uso de uma variável alem de seu scope.
  • Solução: https://play.golang.org/p/sA7NHpkCCg

Na prática: exercício #11

  • Uma das melhores maneiras de aprender é ensinando.
  • Para este exercício escolha o seu código favorito dentre os que vimos estudando funções. Pode ser das aulas ou da seção de exercícios. Então:
    • Faça download e instale isso aqui: https://obsproject.com/
    • Grave um vídeo onde você ensina o tópico em questão
    • Faça upload do vídeo no YouTube
    • Compartilhe o vídeo no Twitter e me marque no tweet (@ellenkorbes)

14 – Ponteiros

O que são ponteiros?

  • Todos os valores ficam armazenados na memória.
  • Toda localização na memória possui um endereço.
  • Um pointeiro se refere a esse endereço.
  • Notações:
    • &variável mostra o endereço de uma variável
      • %T: variável vs. &variável
    • *variável faz de-reference, mostra o valor que consta nesse endereço
    • ????: *&var funciona!
    • *type é um tipo que contem o endereço de um valor do tipo type, nesse caso * não é um operador
  • Exemplo: a := 0; b := &a; *b++
  • Go Playground: https://play.golang.org/p/gC1qGFUYrV

Quando usar ponteiros

  • Ponteiros permitem compartilhar endereços de memória. Isso é útil quando:
    • Não queremos passar grandes volumes de dados pra lá e pra cá
    • Queremos mudar um valor em sua localização original (tudo em Go é pass by value!)
  • Exemplos:
    • x := 0; funçãoquemudaovalordoargumentopra1(x); Print(x)
    • x := 0; funçãoquemudaovalordo*argumentopra1(&x); Print(x)
  • Go Playground: https://play.golang.org/p/VZmfWfw76s

15 – Exercícios: Ninja Nível 7

Na prática: exercício #1

Na prática: exercício #2

  • Crie um struct "pessoa"
  • Crie uma função chamada mudeMe que tenha *pessoa como parâmetro. Essa função deve mudar um valor armazenado no endereço *pessoa.
    • Dica: a maneira "correta" para fazer dereference de um valor em um struct seria (*valor).campo
    • Mas consta uma exceção na documentação. Link: https://golang.org/ref/spec#Selectors
    • "As an exception, if the type of x is a named pointer type and (*x).f is a valid selector expression denoting a field (but not a method),
    • → x.f is shorthand for (*x).f." ←
    • Ou seja, podemos usar tanto o atalho p1.nome quanto o tradicional (*p1).nome
  • Crie um valor do tipo pessoa;
  • Use a função mudeMe e demonstre o resultado.
  • Solução: https://play.golang.org/p/qiYp9leJcn

16 – Aplicações

Documentação JSON

  • Já entendemos ponteiros, já entendemos métodos. Já temos o conhecimento necessário para começar a utilizar a standard library.
  • Nesse vídeo faremos uma orientação sobre como abordar a documentação.
  • Essa aula não foi preparada. Vai ser tudo ao vivo no improviso pra vocês verem como funciona o processo.
    • golang.org → Documents → Package Documentation
    • godoc.org → encoding/json
      • files
      • examples
      • funcs
      • types
      • methods

JSON marshal (ordenação)

JSON unmarshal (desordenação)

A interface Writer

  • A interface writer do pacote io.
  • type Writer interface { Write(p []byte) (n int, err error) }
    • pkg os: func (f *File) Write(b []byte) (n int, err error)
    • pkg json: func NewEncoder(w io.Writer) *Encoder
  • "Println [...] writes to standard output."
    • func Println [...] return Fprintln(os.Stdout, a...)
    • func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
    • Stdout: NewFile(uintptr(syscall.Stdout), "/dev/stdout") (Google: Standard streams)
    • func NewFile(fd uintptr, name string) *File
    • func (f *File) Write(b []byte) (n int, err error)
  • Exemplo:
    • Println
    • Fprintln os.Stdout
    • io.WriteString os.Stdout
    • Ou:
      • func Dial(network, address string) (Conn, error)
      • type Conn interface { [...] Write(b []byte) (n int, err error) [...] }
  • Go Playground:

O pacote sort

Customizando o sort

  • O sort que eu quero não existe. Quero fazer o meu.
  • Para isso podemos usar o func Sort do package sort. Vamos precisar de um sort.Interface.
    • type Interface interface { Len() int; Less(i, j int) bool; Swap(i, j int) }
  • Ou seja, se tivermos um tipo que tenha esses métodos, ao executar sort.Sort(x) as funções que vão rodar são as minhas, não as funções pré-prontas como no exercício anterior.
  • E aí posso fazer do jeito que eu quiser.
  • Exemplo:
    • struct carros: nome, consumo, potencia
    • slice []carros{carro1, carro2, carro3} (Sort ordena slices!)
    • tipo ordenarPorPotencia
    • tipo ordenarPorConsumo
    • tipo ordenarPorLucroProDonoDoPosto
  • Go Playground: https://play.golang.org/p/KOIhAsE3OK

bcrypt

17 – Exercícios: Ninja Nível 8

Na prática: exercício #1

Na prática: exercício #2

Na prática: exercício #3

Na prática: exercício #4

Na prática: exercício #5

18 – Concorrência

Concorrência vs. paralelismo

  • Concorrência é quando abre uma padaria do lado da outra e as duas quebram :)
  • Fun facts:
    • O primeiro CPU dual core "popular" veio em 2006
    • Em 2007 o Google começou a criar a linguagem Go para utilizar essa vantagem
    • Go foi a primeira linguagem criada com multi-cores em mente
    • C, C++, C#, Java, JavaScript, Python, etc., foram todas criadas antes de 2006
    • Ou seja, Go tem uma abordagem única (fácil!) para este tópico
  • E qual a diferença entre concorrência e paralelismo?

Goroutines & WaitGroups

  • O código abaixo é linear. Como fazer as duas funções rodarem concorrentemente?
  • Goroutines!
  • O que são goroutines? São "threads."
  • O que são threads? WP
  • Na prática: go func.
  • Exemplo: código termina antes da go func executar.
  • Ou seja, precisamos de uma maneira pra "sincronizar" isso.
  • Ah, mas então... não.
  • Qualé então? sync.WaitGroup:
  • Um WaitGroup serve para esperar que uma coleção de goroutines termine sua execução.
    • func Add: "Quantas goroutines?"
    • func Done: "Deu!"
    • func Wait: "Espera todo mundo terminar."
  • Ah, mas então... sim!
  • Só pra ver: runtime.NumCPU() & runtime.NumGoroutine()
  • Go Playground: https://play.golang.org/p/8iiqLX4sWc

Discussão: Condição de corrida

Condição de corrida

Mutex

Atomic

19 – Seu Ambiente de Desenvolvimento

O terminal

  • Terminologia:
    • GUI: Graphical User Interface
    • CLI: Command Line Interface
      • Terminal, console, etc
    • Unix, Linux, Mac:
      • Shell, bash
    • Windows: Command prompt, cmd, dos prompt, powershell
  • Shell/bash commands:
    • pwd
    • ls
      • ls -la
      • Permissions: owner, group, world
      • r, w, x → 4, 2, 1 (d = directory)
      • rwxrwxrwx = owner, group, world
    • touch
    • clear
    • chmod
      • chmod options permissions filename
      • chmod 777 arquivo.ext
    • cd
      • cd ../
      • cd qualquer/pasta/
    • env
    • rm
      • rm -rf
    • .bash_profile & .bashrc
      • .bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.
      • When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt.
    • nano
    • cat
    • grep
      • cat temp2.txt | grep enter
      • ls | grep -i documents

Go workspace & environment variables

  • $GOPATH/ bin/ pkg/ src/ github.com/ <Nome do usuário (github.com)>/ / / / / ... /
  • GOROOT: onde os binários da instalação do Go foram instalados
    • GOROOT="/usr/lib/go"
  • GOPATH: onde seus arquivos de trabalho, seu workspace, fica localizado
    • GOPATH="/home/ellen/go"
    • export GOPATH=$HOME/go (.bashrc)
  • Package management? go get.
    • Na prática → e.g. gouuid

IDE's

Comandos Go

  • go version
  • go env
  • go help
  • go fmt
    • ./…
  • go run
    • go run
    • go run *.go
  • go build
    • para um executável:
      • gera o arquivo binário
      • informa caso tenham havido erros
      • caso não hajam erros, cria um executável e salva-o no diretório atual
    • para um pacote:
      • gera o arquivo
      • informa caso tenham havido erros
      • descarta o executável
  • go install
    • para um executável:
      • faz o build
      • nomeia o arquivo com o nome do diretório atual
      • salva o arquivo binário em $GOPATH/bin
    • para um pacote:
      • faz o build
      • salva o arquivo binário em $GOPATH/pkg
      • cria archive files (arquivo.a), os arquivos pré-compilados utilizados pelos imports
  • flags
    • "-race"

Repositórios no GitHub

  • Git foi feito pelo Linus Torvalds. O cara que criou o Linux.
  • GitHub, GitLab.
  • Como funciona?
    • Vá em github.com e crie um repo
    • Crie uma pasta com o mesmo nome no seu $GOPATH
      • $GOPATH/src/github.com//
    • Rode “git init” nesta pasta
    • Adicione arquivos, e.g. README.md e .gitignore
    • git add -A
    • git commit -m “here’s some commit message”
    • git remote add origin git@github.com:username/repo.git
    • git push -u origin master
  • Comandos:
    • git status
    • git add --all
    • git commit -m "mensagem"
    • git push

Explorando o GitHub

  • Clonando um repo git clone
  • SSH
    • Mac/Linux: ssh-keygen -t rsa
      • id_rsa: Esta é sua chave privada, que fica no diretório ~/.ssh, e serve para verificar sua chave pública.
      • id_rsa.pub: Esta é sua chave pública, que você pode compartilhar.
    • Windows: Google :)
  • git remote
    • git remote get-url origin
    • git remote blablabla ← help
  • Truque sujo: apaga tudo e clona denovo. (Não recomendo se o repo tiver 4 GB...)

Compilação cruzada

Pacotes

  • Opção 1: uma pasta, vários arquivos.
    • package declaration em todos os arquivos
    • package scope: um elemento de um arquivo é acessível de todos os arquivos
    • imports tem file scope
  • Opção 2: separando por packages.
    • pastas diferentes
    • requer imports
    • para usar: package.Função()
  • Exportado vs. não-exportado, ou seja, visível vs. não-visível
    • Em Go não utilizamos os termos "público" e "privado" como em outras linguagens
    • É somente questão de capitalização
      • Com maiúscula: exportado, visível fora do package
      • Com minúscula: não exportado, não utilizável fora do package
  • Artigo: https://rakyll.org/style-packages/
  • Exemplo: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/19_seu-ambiente-de-desenvolvimento/pacotes

20 – Exercícios: Ninja Nível 9

Na prática: exercício #1

Na prática: exercício #2

  • Esse exercício vai reforçar seus conhecimentos sobre conjuntos de métodos.
    • Crie um tipo para um struct chamado "pessoa"
    • Crie um método "falar" para este tipo que tenha um receiver ponteiro (*pessoa)
    • Crie uma interface, "humanos", que seja implementada por tipos com o método "falar"
    • Crie uma função "dizerAlgumaCoisa" cujo parâmetro seja do tipo "humanos" e que chame o método "falar"
    • Demonstre no seu código:
      • Que você pode utilizar um valor do tipo "*pessoa" na função "dizerAlgumaCoisa"
      • Que você não pode utilizar um valor do tipo "pessoa" na função "dizerAlgumaCoisa"
  • Se precisar de dicas, veja: https://gobyexample.com/interfaces
  • Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/02/main.go

Na prática: exercício #3

  • Utilizando goroutines, crie um programa incrementador:
    • Tenha uma variável com o valor da contagem
    • Crie um monte de goroutines, onde cada uma deve:
      • Ler o valor do contador
      • Salvar este valor
      • Fazer yield da thread com runtime.Gosched()
      • Incrementar o valor salvo
      • Copiar o novo valor para a variável inicial
    • Utilize WaitGroups para que seu programa não finalize antes de suas goroutines.
    • Demonstre que há uma condição de corrida utilizando a flag -race
  • Solução: https://github.com/ellenkorbes/aprendago/blob/master/c%C3%B3digo/20_exercicios-ninja-9/03/main.go

Na prática: exercício #4

Na prática: exercício #5

Na prática: exercício #6

Na prática: exercício #7

  • "If you do not leave your comfort zone, you do not remember the trip" — Brian Chesky
  • Faça download e instale: https://obsproject.com/
  • Escolha um tópico dos que vimos até agora. Sugestões:
    • Motivos para utilizar Go
    • Instalando Go
    • Configurando as environment variables (e.g. GOPATH)
    • Hello world
    • go commands e.g. go help
    • Variáveis
    • O operador curto de declaração
    • Constantes
    • Loops
      • init, cond, post
      • break
      • continue
    • Funções
    • func (receiver) identifier(params) (returns) { code }
    • Métodos
    • Interfaces
    • Conjuntos de métodos
    • Tipos
      • Conversão?
    • Concorrência vs. paralelismo
    • Goroutines
    • WaitGroups
    • Mutex
  • Grave um vídeo onde você ensina o tópico em questão.
  • Faça upload do vídeo no YouTube.
  • Compartilhe o vídeo no Twitter e me marque no tweet (@ellenkorbes).

21 – Canais

Entendendo canais

  • Canais são o Jeito Certo® de fazer sincronização e código concorrente.
  • Eles nos permitem trasmitir valores entre goroutines.
  • Servem pra coordenar, sincronizar, orquestrar, e buffering.
  • Na prática:
    • make(chan type, b)
    • <- 42
    • <-c
  • Canais bloqueiam:
    • Eles são como corredores em uma corrida de revezamento
    • Eles tem que "passar o bastão" de maneira sincronizada
    • Se um corredor tentar passar o bastão pro próximo, mas o próximo corredor não estiver lá...
    • Ou se um corredor ficar esperando receber o bastão, mas ninguem entregar...
    • ...não dá certo.
  • Exemplos:
    • Poe um valor num canal e faz um print. Block.
      • Código acima com goroutine.
      • Ou com buffer. Via de regra: má idéia; é legal em certas situações, mas em geral é melhor sempre passar o bastão de maneira sincronizada.
  • Interessante: ref/spec → types
  • Código:

Canais direcionais & utilizando canais

Range e close

Select

  • Select é como switch, só que pra canais, e não é sequencial.
  • "A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready." — https://tour.golang.org/concurrency/5
  • Na prática:
    • Exemplo 1:
      • Duas go funcs enviando X/2 numeros cada uma pra um canal
      • For loop X valores, select case <-x
    • Exemplo 2:
      • Func 1 recebe X valores de canal, depois manda qualquer coisa pra chan quit
      • Func 2 for infinito, select: case envia pra canal, case recebe de quit
    • Exemplo 3:
      • Chans par, ímpar, quit
      • Func send manda números pares pra um canal, ímpares pra outro, e fecha/quit
      • Func receive é um select entre os três canais, encerra no quit
      • Problema!
  • Go Playground:

A expressão comma ok

Convergência

  • Observamos convergência quando informação de vários canais é enviada a um número menor de canais.
  • Interessante: <- <-
  • Na prática, exemplos:
      1. Todd:
      • Canais par, ímpar, e converge.
      • Func send manda pares pra um, ímpares pro outro, depois fecha.
      • Func receive cria duas go funcs, cada uma com um for range, enviando dados dos canais par e ímpar pro canal converge. Não esquecer de WGs!
      • Por fim um range retira todas as informações do canal converge.
      1. Rob Pike (palestra Go Concurrency Patterns):
      • Func trabalho cria um canal, cria uma go func que manda dados pra esse canal, e retorna o canal. Interessante: time.Duration(rand.Intn(1e3))
      • Func converge toma dois canais, cria um canal novo, e cria duas go funcs com for infinito que passa tudo para o canal novo. Retorna o canal novo.
      • Por fim chamamos canal := converge(trabalho(nome1), trabalho(nome2)) e usamos um for para receber dados do canal var.
  • Código: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/21_canais/07

Divergência

  • Divergência é o contrário de convergência :)
  • Na prática, exemplos:
      1. Um stream vira centenas de go funcs que depois convergem.
      • Dois canais.
      • Uma func manda X números ao primeiro canal.
      • Outra func faz um range deste canal, e para cada ítem lança uma go func que poe o retorno de trabalho() no canal dois.
      • Trabalho() é um timer aleatório pra simular workload.
      • Por fim, range canal dois demonstra os valores.
      1. Com throttling! Ou seja, com um número máximo de go funcs.
      • Ídem acima, mas a func que lança go funcs é assim:
      • Cria X go funcs, cada uma com um range no primeiro canal que, para cada item, poe o retorno de trabalho() no canal dois.
  • Código: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/21_canais/08

Context

22 – Exercícios: Ninja Nível 10

Na prática: exercício #1

Na prática: exercício #2

Na prática: exercício #3

Na prática: exercício #4

Na prática: exercício #5

Na prática: exercício #6

Na prática: exercício #7

23 – Tratamento de Erros

Entendendo erros

  • Para quem já programa em outras linguagens:
    • Em Go não temos exceções. → https://golang.org/doc/faq#exceptions
    • "We believe that coupling exceptions to a control structure, as in the try-catch-finally idiom, results in convoluted code."
    • "Go's multi-value returns make it easy to report an error without overloading the return value. A canonical error type, coupled with Go's other features, makes error handling pleasant but quite different from that in other languages."
    • Aventureiros: https://blog.golang.org/error-handling-and-go
  • É interessante criar o hábito de lidar com erros imediatamente, similar a e.g. defer close.
  • package builtin, type error interface
  • package errors

Verificando erros

Print & log

Recover

Erros com informações adicionais

24 – Exercícios: Ninja Nível 11

Na prática: exercício #1

Na prática: exercício #2

Na prática: exercício #3

Na prática: exercício #4

Na prática: exercício #5

  • Nos capítulos seguintes, uma das coisas que veremos é testes.
  • Para testar sua habilidade de se virar por conta própria... desafio:
    • Utilizando as seguintes fontes: https://godoc.org/testing & http://www.golang-book.com/books/intro/12
    • Tente descobrir por conta própria como funcionam testes em Go.
    • Pode usar tradutor automático, pode rodar código na sua máquina, pode procurar no Google. Vale tudo.
    • O exercício é: crie um teste simples de uma função ou método ou pedaço qualquer de código.

25 – Documentação

Introdução

  • Antes de escrever documentação, vamos ver como lê-la. Temos algumas possibilidades:
    • golang.org → documentação da standard library
    • godoc.org → documentação da standard library e outros
    • go doc → comando para ler documentação na linha de comando
    • godoc → idem acima, para pode-se servir a documentação local via http

go doc

  • go help doc
  • go doc demonstra a documentação de um package, const, func, type, var, método, etc.
  • go doc aceita zero, um, ou dois argumentos:
    • zero: demonstra a documentação do package do diretório atual
    • um: toma argumentos nos padrões abaixo
      • go doc
      • go doc [.]
      • go doc [.][.]
      • go doc [.][.]
    • dois: o primeiro argumento deve ser o nome do package
      • go doc [.]

godoc

  • godoc extrai e gera documentação de programas em Go. Funciona de duas maneiras:
    • Sem o flag http é um comando normal, mostra a documentação no stdout e é isso aí. Pode conter o flag src, que mostra o código fonte.
    • Com o flag http roda um servidor web local e mostra a documentação como página web.
  • Exemplo: godoc -http=:8080 → http://localhost:8080/

godoc.org

  • Documentação da standard library e outros
  • Como colocar a documentação do seu package no godoc.org
  • refresh, delete

Escrevendo documentação

  • Documentação é uma parte extremamente importante de fazer com que software seja acessível e sustentável.
  • Documentação deve ser bem escrita e correta, mas tambem fácil de escrever e manter.
  • Deve ser acoplada com o código e evoluir junto com este. Quanto mais fácil for para os programadores criarem boa documentação... melhor fica pra todos os envolvidos.
  • godoc:
    • Analisa código fonte em Go, incluindo comentários, e gera documentação em HTML ou texto
    • O resultado é uma documentação firmemente atrelada ao código que documenta.
    • Por exemplo, na interface web de godoc pode-se navegar da documentação à implementação de um código com apenas um clique.
    • https://blog.golang.org/godoc-documenting-go-code
  • Na prática:
    • Para documentar um tipo, uma variável, uma constante, ou um pacote, escreva um comentário imediatamente antes de sua declaração, sem linhas em branco
    • Comece a frase com o nome do elemento. No caso de pacotes, a primeira linha aparece no "package list."
    • Caso esteja escrevendo bastante documentação, utilize um arquivo doc.go. Exemplo: package fmt.
  • A melhor parte dessa abordagem minimalista é que é super fácil de usar. Como resultado, muita coisa em Go, incluindo toda a standard library, já segue estas convenções.
  • Outro exemplo: errors package.
  • Código: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/25_escrevendo-documentacao

26 – Exercícios: Ninja Nível 12

Na prática: exercício #1

  • Crie um package "cachorro".
    • Este package deverá exportar uma função Idade, que toma como parâmetro um número de anos e retorna a idade equivalente em anos caninos. (1 ano humano → 7 anos caninos)
    • Documente seu código com comentários, e utilize a função Idade na sua função main.
  • Rode seu programa para verificar se ele funciona.
  • Rode um local server com godoc e leia sua documentação.
  • Solução: https://github.com/ellenkorbes/aprendago/tree/master/c%C3%B3digo/26_exercicios-ninja-12/01_cachorro

Na prática: exercício #2

  • Coloque seu código no GitHub.
  • Faça sua documentação aparecer em godoc.org, e tire um screenshot.
  • Delete seu código do GitHub.
  • Faça um refresh em godoc.org e veja se seu código sumiu.
  • Compartilhe seu exercício aqui: #79

Na prática: exercício #3

  • Use godoc na linha de comando para ver a documentação sobre:
    • fmt
    • fmt Print
    • strings
    • strconv

27 – Testes & Benchmarking

Introdução

Testes em tabela

  • Podemos escrever testes em série para testar variedades de situações.
  • Exemplo:
    • struct test, fields: data []int, answer int
    • tests := []test{[]int{}, int}
    • range tests

Testes como exemplos

  • Outra maneira é fazer testes como exemplos.
  • Estes exemplos são os mesmos que aparecem na documentação.
  • Para exemplos o formato é "func ExampleFuncao()"
  • Deve haver um comentário "// Output: resultado", que é o que será testado
  • Para visualizar seu exemplo na documentação, fazemos o de sempre:
    • godoc -http :8080
  • Tanto para testes quanto para exemplos podemos utilizar: go test ./...
  • Mais: https://blog.golang.org/examples

go fmt, govet e golint

  • gofmt: formata o código
  • go vet: correctness → procura constructs suspeitos
  • golint: suggestions → procura coding style ruim

Benchmark

Cobertura

  • "Cobertura" em se tratando de testes se refere a quanto do seu código, percentualmente, está sendo testado. (E antes que alguem fique neurótico querendo 100%: em geral, 70-80% tá ótimo.)
  • A flag -cover faz a análise de cobertura do nosso código.
  • Podemos utilizar a flag -coverprofile para salvar a análise de cobertura em um arquivo.
  • Na prática:
    • go test -cover
    • go test -coverprofile c.out
    • go tool cover -html=c.out ← abre no browser
    • go tool cover -h ← para mais detalhes