{"id":18023583,"url":"https://github.com/jeffotoni/codenation.dev","last_synced_at":"2025-03-27T00:30:41.127Z","repository":{"id":57705632,"uuid":"184601594","full_name":"jeffotoni/codenation.dev","owner":"jeffotoni","description":"AceleraDev Full Stack - Go, 4 SEMANAS DE GO E DEPOIS REACT","archived":false,"fork":false,"pushed_at":"2019-12-23T02:11:40.000Z","size":66893,"stargazers_count":26,"open_issues_count":0,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-22T17:24:51.706Z","etag":null,"topics":["go","golang"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffotoni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-02T15:02:59.000Z","updated_at":"2025-03-10T13:13:45.000Z","dependencies_parsed_at":"2022-08-29T05:30:31.581Z","dependency_job_id":null,"html_url":"https://github.com/jeffotoni/codenation.dev","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fcodenation.dev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fcodenation.dev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fcodenation.dev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fcodenation.dev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffotoni","download_url":"https://codeload.github.com/jeffotoni/codenation.dev/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245760541,"owners_count":20667886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang"],"created_at":"2024-10-30T07:09:57.237Z","updated_at":"2025-03-27T00:30:38.865Z","avatar_url":"https://github.com/jeffotoni.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# codenation.dev\n\nAceleraDev Full Stack - Go, 4 SEMANAS DE GO E DEPOIS REACT.\n\n### Público-alvo\nCurso de programação usando a linguagem Go abordando conceitos teóricos e práticos é voltado para estudantes, profissionais ou entusiastas que desejam adquirir conhecimentos em uma das linguagens que mais cresce atualmente afim de melhores colocações no mercado de trabalho ou auto conhecimento.\n\n### Objetivo\nO objetivo deste curso é capacitar os profissionais para o desenvolvimento de aplicações em Go. Para isso, o curso abordará os principais conceitos e tecnologias utilizadas no jeito Go de fazer as coisas. Iremos reforçar as boas práticas de programação, falar um pouco de métodos ágeis e abordar em um contexto geral problemas e como podemos resolvê-los usando Go.\nApós a conclusão do curso “Programação Go”, o aluno estará apto a desenvolver aplicações na linguagem Go, com condição de continuar e explorar ainda mais os aspectos da linguagem.\n\n## MÓDULO 01 Introdução a Linguagem\n\n- [Overview](#Overview)\n    - [Golang](#Golang)\n      - [Linguagem Go](#Linguagem-Go)\n      - [Onde posso utilizar Go](#Onde-posso-utilizar-Go)      \n      - [O inicio de tudo](#O-inicio-de-tudo)\n      - [Por que meu binário hello world é tão grande](#Por-que-meu-binário-hello-world-é-tão-grande)\n- [Introdução a instalação](#Introdução-a-instalação)\n  - [Instalação](#Instalação)\n    - [Linux](#Linux)\n    - [$GOPATH](#gopath)\n    - [Teste nossa instalação](#Teste-nossa-instalação)\n    - [Área de trabalho](#área-de-trabalho)\n    - [Fora de $GOPATH](#Fora-de-GOPATH)\n- [Instalação com Docker](#Instalação-com-Docker)\n\t- [Instalar Docker para Go](#Instalar-Docker-para-Go)\n\t- [Compile seu aplicativo dentro do contêiner Docker](#Compile-seu-aplicativo-dentro-do-contêiner-Docker)\n\t- [Cross-compile seu aplicativo dentro do contêiner Docker](#Cross-compile-seu-aplicativo-dentro-do-contêiner-Docker)\n- [Introdução Golang](#Introdução-Golang)\n  - [Linguagem Golang](#Linguagem-Golang)\n    - [Keywords](#Keywords)\n    - [Operadores e Pontuação](#Operadores-e-Pontuação)\n    - [Println Print](#Println-Print)\n    - [Bufio NewWriter](#Bufio-NewWriter)\n    - [Func Main](#Func-Main)\n- [Comandos Go](#Comandos-Go)\n   - [Introdução aos comandos Go](#Introdução-aos-comandos-Go)\n   - [Go Run](#Go-Run) \n   - [Go Build](#Go-Build)\n   - [Instalar Go](#Instalar-Go)\n   - [Go Get](#Go-Get)\n   - [Go Mod](#Go-Mod)\n   - [Go Mod Init](#Go-Mod-Init)\n   - [Go Mod Vendor](#Go-Mod-Vendor)\n   - [GO-1.11-Módulo](#Go-111-módulo)\n   - [Go Test](#Go-Test)\n\n## MÓDULO 02 Aprofundando na Linguagem\n\n- [Tipos](#Tipos)\n   - [Numeric Types](#Numeric-Types)\n   - [String Types](#String-Types)\n   - [Pointer Types](#Pointer-Types)\n   - [Array Types](#Array-Types)\n   - [Slice Types](#Slice-Types)\n   - [Struct Types](#Struct-Types)\n   - [Struct In C](#Struct-In-C)\n   - [Struct Type Tags Json](#Struct-Type-Tags-Json)\n   - [Fatih Structs to Map](#Fatih-Structs-to-Map)\n   - [Map Types](#Map-Types)\n   - [Map Literals Continued](#Map-Literals-Continued)\n   - [Channel Types](#Channel-Types)\n   - [Blank Identifier](#Blank-Identifier)\n   - [Tipos de interface](#Tipos-de-interface)\n\t - [Aqui está uma interface como um método](#Aqui-está-uma-interface-como-um-método)\n\t - [Interface como tipo](#Interface-como-tipo)\n- [Estruturas de Controle](#Estruturas-de-Controle)\n  - [Ao-Controle](#Ao-Controle)\n    - [Retorno de Controle](#Retorno-de-Controle)\n    - [Controle Goto](#Controle-Goto)\n    - [Control if Else](#Control-if-Else)\n    - [Control for break continue](#Control-for-break-continue)\n    - [Control switch case break](#Control-switch-case-break)\n    - [Etiqueta de Controle](#Etiqueta-de-Controle)\n    - [Faixa de Controle](#Faixa-de-Controle)\n- [Erros](#Erros)\n  - [Introdução aos Erros](#Introdução-aos-Erros)\n    - [Como funciona o controle de erros](#Como-funciona-o-controle-de-erros)\n    - [Novos Erros](#Novos-Erros)\n    - [Erros Personalizados](#Erros-Personalizados)    \n    - [fmt Errorf](#fmt-Errorf)\n- [Funções](#Funções)\n  - [Introução as Funções](#Introdução-as-Funções)\n    - [Retornar vários valores](#Retornar-vários-valores) \n    - [Funções Variadic](#Funções-Variadic) \n    - [Funções como um parâmetro](#Funções-como-um-parâmetro) \n    - [Fechamentos](#Fechamentos)\n    - [Recursão](#Recursão)\n    - [Funções Asynchronous](#Funções-Asynchronous)\n- [Defer](#Defer)\n- [Exercício 1](#Exercício-1)\n\n\n## Overview\n\n### Golang\n\n#### Linguagem Go\n\nGo é uma linguagem poderosa quando se trata de **concorrência e alto desempenho**, com uma arquitetura limpa e eficiente. Ela cresce ano após ano e todos os dias as comunidades crescem ainda mais.\n\nAlguns paradigmas foram quebrados para torná-lo uma linguagem de **alto desempenho**, onde a concorrência é um dos seus pontos fortes. O Go facilita a criação de programas que aproveitam ao máximo as máquinas multicore e em rede, enquanto o novo sistema de tipos permite que você crie programas flexíveis e modulares.\n\nÉ uma linguagem rápida e **estaticamente compilada** que se parece com uma linguagem **interpretada dinamicamente**. Este recurso **Go** se torna uma linguagem única como o assunto é web.\n\nGo é uma linguagem de programação compilada, concorrrente, com tipagem forte e estaticamente tipada. É uma linguagem de **\"Uso Geral\"** que pode ser usada para resolver vários problemas e em diferentes áreas. Problemas envolvendo concorrência, aplicações web, aplicações de alto desempenho, desenvolvimento de APIs, soquetes de comunicação etc ... É onde a linguagem está se tornando cada vez mais proeminente no mercado e nas comunidades.\n\n```bash\n - Compilado\n - Linguagem estática\n - Linguagem estática com tipos dinâmicos (Em Go seria o uso de tipo como interface)\n - Estaticamente tipada (declarado o tipo ele não muda)\n - Tipagem forte (um mesmo dado não é tratado como se fosse de outro tipo)\n - Compilada estaticamente\n - Concorrente\n - Simples\n - Produtivo\n - GC (Garbage Coletor)\n - Runtime (Implementa coleta de lixo, concorrencia, gerenciamento de pilha e outros \n recursos críticos da linguagem em tempo de execução, algoritimo implementado é Dijkstra)\n\nObs: É importante entender, no entanto, que o tempo de execução do \nGo não inclui uma máquina virtual. Os programas Go são compilados \npara o código de máquina nativo.\n ```\n\n##### Onde posso utilizar Go:\n\n```bash\n. Web backend (com diversos frameworks disponíveis)\n. Web Assembly (um dos frameworks vugu)\n. Microservices (alguns frameworks: Go Micro, Go Kit, Gizmo, Kite)\n. Fragments services (Termo citado pelo @jeffotoni em um grupo de discussão de microservices)\n. Lambdas (FaaS example)\n. Client Server\n. IoT (alguns frameworks)\n. Boots (alguns aqui)\n. Aplicações Client que usam tecnologia Web \n. Desktop Usando Qt+QML, Lib Nativa Win (example Qt, widgets Qt, Qml)\n```\n\n### O inicio de tudo\n\nExistem inúmeras linguagens de programação e cada uma nasceu com um propósito: “resolver problemas”. As linguagens são ferramentas onde teremos que saber utilizá-las no momento certo. Falando “como desenvolvedor” quanto mais poliglota conseguir ser melhor será para sua carreira profissional e para um melhor entendimento e compreensão da diversidade deste ecossistema.\n\nO objetivo deste curso é apresentar o que é a linguagem Go e, porque ela é tão poderosa. Apresentando alguns conceitos e pontos importantes sobre a linguagem Go.\n\nA equipe de desenvolvedores do Go dizem que sua criação é uma tentativa de tornar os programadores mais produtivos. Melhorando o processo de desenvolvimento de software no Google. O primeiro objetivo foi criar uma linguagem melhor para enfrentar os desafios da simultaneidade escalável, ou seja software que lida com muitas preocupações simultaneamente, um exemplo seria a coordenação de mil servidores back-end enviando tráfego de rede todo o tempo.\n\nManter a linguagem Go pequena permite objetivos mais importantes. Ser pequeno torna o Go mais fácil de aprender, mais fácil de entender, mais fácil de implementar, mais fácil de reimplementar, mais fácil de depurar, mais fácil de ajustar e mais fácil de evoluir. Fazer menos permite mais. É uma expressão utilizada pela equipe de desenvolvimento do Go: “Do Less. Enable More” seria o equilíbrio entre os universo de problemas existentes e o que Go poderá ajudar a resolver bem tais problemas. Go explicitamente não foi projetado para resolver todos os problemas em vez disso fizeram o suficiente para possamos criar as próprias soluções personalizadas com facilidade, mas deixando bem claro que Go não pode fazer tudo.\n\nNão temos dúvidas que desempenho ou simultaneidade são características importantes e muito relevante na linguagem Go mas Simplicidade, Legibilidade e Produtividade tem um peso muito grande para que tudo ocorra de forma equilibrada e saudável.\n\n - Existem idiomas que são um pouco mais rápidos que o Go, mas certamente não são tão simples quanto o Go. \n - Existem linguagens que tornam a concorrência seu objetivo mais elevado, mas não são tão legíveis nem produtivas.\n - Desempenho e simultaneidade são atributos importantes, mas não tão importantes quanto simplicidade, legibilidade e produtividade.\n \n A **Simplicidade** é pré-requisito para confiabilidade, escrevemos códigos para máquinas certo? Não necessariamente, escrevemos código para outros humanos conseguirem manter e da continuidade o que iniciamos a máquina somente executa podemos dizer que  algo secundário uma conseguencia.\n \n A **Legibilidade** é essencial para a manutenção, e o software não puder ser mantido, ele será reescrito; e essa pode ser a última vez que sua empresa investirá em Go. Se você está escrevendo um programa para si mesmo, talvez ele tenha que ser executado apenas uma vez, ou você seja a única pessoa que já o verá, então faça o que já funciona para você. Mas se esse for um software com o qual mais de uma pessoa contribuirá ou que será usado por pessoas durante um período de tempo suficiente que os requisitos, recursos ou o ambiente é executado em alterações, seu objetivo deve ser para o seu programa para ser sustentável .\n\nA **Produtividade** depende diretamente do design, que é a arte de organizar o código para funcionar hoje e ser mutável para sempre. A piada diz que o Go foi projetado enquanto aguardava a compilação de um programa em C++. Compilação rápida é uma característica fundamental do Go e uma ferramenta chave de recrutamento para atrair novos desenvolvedores. \n\nGo foi projetado pelo Google em 2007 para melhorar a produtividade de programação em uma era de multicore, rede de máquinas e grandes bases de código. Os designers queriam abordar críticas de outras línguas em uso no Google, mas manter suas características úteis.\n\nOs criadores Rob Pike, Ken Thompson e Robert Griesemer mantiveram a sintaxe de Go semelhante ao C. No final de 2008 Russ Cox juntou-se a equipe e ajudou a mudar a linguagem e as bibliotecas de protótipo para realidade.\n\n**A linguagem Go** foi lançada em 2009 com propósito de facilitar a resolução de problemas quando o assunto é desenvolvimento em camadas de rede, escalabilidade, desempenho, produtividade e o mais importante concorrência. O próprio Rob Pike declarou que “Go foi projetado para tratar de um conjunto de problemas de engenharia de software a que estávamos expostos na construção de grandes softwares de servidor”.\n\nGo teve influências de diversas linguagens de programação e paradigmas diferentes dentre elas: Alef, APL, BCPL, C, CSP, Limbo, Modula, Newsqueak, Oberon, occam, Pascal, Smalltalk e Cristal, percebe-se que utilizaram do que tinham de melhor e criou algo novo e enxuto, com o mínimo necessário para resolver os problemas propostos, sem perder sua simplicidade. Acredito que isto podemos chamar de inovação. Go inovou ao quebrar os paradigmas de linguagens e implementar algo novo de forma simples e muito poderosa.\n\n\n#### Por que meu binário hello world é tão grande?\n\nO vinculador no gc toolchain cria binários vinculados estaticamente por padrão. Portanto, todos os binários Go incluem o tempo de execução Go, juntamente com as informações do tipo em tempo de execução necessárias para oferecer suporte a verificações de tipos dinâmicos, reflexos e até mesmo rastreamentos de pilha em tempo de pânico.\n\nUm simples programa C \"hello, world\" compilado e linkado estaticamente usando o gcc no Linux é de cerca de 750 kB, incluindo uma implementação do printf. Um programa Go equivalente usando fmt.Printf pesa alguns megabytes, mas isso inclui suporte a tempo de execução mais poderoso e informações de tipo e depuração.\n\nUm programa Go compilado com gc pode ser vinculado ao sinalizador -ldflags=-w para desabilitar a geração de DWARF, removendo as informações de depuração do binário, mas sem nenhuma outra perda de funcionalidade. Isso pode reduzir substancialmente o tamanho binário.\n\nExemplo:\n\n```bash\n$ go build -ldflags=-w -o helo hello.go\n```\n\n## Introdução a instalação\n\nEm golang a instalação é muito simples e prática, para Linux, Mac e Windows.\n\nBasta copiar os arquivos para o diretório correto para cada sistema operacional e exportar os caminhos para o ambiente e solicitar, golang está instalado.\n\nVamos dar uma olhada em como fazemos isso.\n\n### Instalação\n---\n\nVamos baixar o arquivo, descompactá-lo e instalá-lo em/usr/local/go, se tivermos golang já instalado na máquina teremos que remover o existente para deixar nossa instalação como única.\nVamos criar nosso diretório em nosso espaço de trabalho e testar para ver se tudo correu bem\n\n#### Linux\n\n```bash\n$ sudo rm -rf/usr/local/go\n$ wget https://dl.google.com/go/go1.12.4.linux-amd64.tar.gz\n$ sudo tar C/usr/local -xzf vai $ VERSION. $ OS- $ ARCH.tar.gz\n```\n\n#### $GOPATH\n\n$GOPATH é o golang em seu $HOME, isso é necessário para que seus projetos usem o pkg e construam corretamente. Isso era obrigatório para todas as versões anteriores à versão 1.11. O legal é que a partir de agora não teremos que criar projetos no $GOPATH, podemos criar em qualquer outro diretório que não esteja no $GOPATH.\n\nEste é o link para a proposta de versão [Proposta: Módulos Go Versionados] (https://go.googlesource.com/proposal/+/master/design/24301-versioned-go.md/) ou [Go 1.11 Modules] ( https://github.com/golang/go/wiki/Modules/)\n\nVamos detalhar como trabalhar com **go mod**, foi uma das melhores experiências que tive para projetos de versionamento usando Golang.\n\nVamos configurar nosso ambiente para rodar o Go. Adicione **/usr/local/go/bin** à variável de ambiente PATH. Você pode fazer isso adicionando esta linha ao seu **/etc/profile** (para uma instalação em todo o sistema) ou **$HOME/.profile**.\n\n```bash\n$ export PATH = $PATH:/usr/local/go/bin\n```\n\n** Nota**: as alterações feitas em um arquivo de perfil podem não se aplicar até a próxima vez que você fizer login no seu computador. Para aplicar as alterações imediatamente, basta executar os comandos do shell diretamente ou executá-los a partir do perfil usando um comando como o source $HOME/.profile.\n\n```bash\n$ echo \"exportar GOPATH = $HOME/go\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH = $ CAMINHO:/usr/local/go/bin\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH = $PATH: $GOPATH/bin\" \u003e\u003e $HOME/.profile\n\nor\n\n$ echo \"exportar GOPATH = $HOME/go\" \u003e\u003e $HOME/.zshrc\n$ echo \"export PATH = $ CAMINHO:/usr/local/go/bin\" \u003e\u003e $HOME/.zshrc\n$ echo \"export PATH = $PATH: $GOPATH/bin\" \u003e\u003e $HOME/.zshrc\n```\n\n#### Teste nossa instalação\n\nVamos executar a versão para ver se tudo está correto.\n\n```bash\n$ go version\ngo version go1.12.4 linux/amd64\n```\n\nVerifique se o Go está instalado corretamente configurando um espaço de trabalho e construindo um programa simples, da seguinte maneira.\n\nCrie o seu **espaço de trabalho** diretório, $HOME/go. (Se você quiser usar um diretório diferente, precisará definir a variável de ambiente $GOPATH.)\n\nEm seguida, faça o diretório src/hello dentro de sua área de trabalho e, nesse diretório, crie um arquivo chamado hello.go que se pareça com:\n\n#### Área de trabalho\n\nO espaço de trabalho é o nosso local de trabalho, onde organizaremos nossos diretórios com nossos projetos. Como mostrado acima, até **Go versão 1.12** fomos forçados a fazer tudo no espaço de trabalho. $GOPATH abaixo do Projeto.\n\n**Exemplo Hello**\n\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go\n$ mkdir $HOME/go/src\n$ mkdir $HOME/go/src/hello\n$ vim $HOME/go/src/hello/hello.go\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-hello\n      |-hello.go\n```\n\n**Example Project**\n\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go/src/project1\n$ mkdir $HOME/go/src/project1/my-pkg\n$ mkdir $HOME/go/src/project1/my-cmd\n$ mkdir $HOME/go/src/project1/my-vendor\n$ mkdir $HOME/go/src/project1/my-logs\n$ mkdir $HOME/go/src/project1/my-models\n$ mkdir $HOME/go/src/project1/my-repo\n$ mkdir $HOME/go/src/project1/my-handler\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-github.com/user/project1/\n        |-cmd (of project1)\n          |-main.go\n        |-vendor\n        |-logs\n        |-models\n        |-repo\n        |-handler\n    |-github.com/user/project2/\n      ....\n      ....\n```\n\n```bash\n$GOPATH/\n  | -src\n    | -github.com/user/project1/\n        | -cmd (do projeto1)\n          | -main.go\n        | -vendor\n        | -logs\n        | -models\n        | -repo\n        | manipulador\n    | -github.com/user/project2/\n      ....\n      ....\n```\n\nA variável de ambiente $GOPATH informa a ferramenta Go onde sua área de trabalho está localizada.\n\n```ir\n$ go get github.com/user/project1\n```\n\nO comando **go get** busca repositórios de origem da Internet e os coloca em sua área de trabalho.\nOs caminhos do pacote são importantes para a ferramenta Ir. Usar \"github.com/...\" significa que a ferramenta sabe como buscar seu repositório.\n\nNo cenário acima, tudo teria que ficar em nosso **$GOPATH** para que nossos projetos funcionassem corretamente.\n\n#### Fora de $GOPATH\n\nAgora podemos fazer nossos projetos sem estar em $GOPATH, podemos, por exemplo, fazê-lo em qualquer diretório.\n\n**Projeto fora do GOPATH**\n\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/2019/project1\n$ mkdir $HOME/2019/project1/my-pkg\n$ mkdir $HOME/2019/project1/my-cmd\n$ mkdir $HOME/2019/project1/my-logs\n$ mkdir $HOME/2019/project1/my-models\n$ mkdir $HOME/2019/project1/my-repo\n$ mkdir $HOME/2019/project1/my-handler\n```\n```bash\n$HOME/\n  |-2019\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nNós podemos colocar o nosso projeto em qualquer diretório agora.\n\n```bash\n$HOME/\n  |-any-directory\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nPara o cenário acima, teremos que usar **go mod** em nosso projeto para que todos os pacotes externos possam funcionar corretamente, assim poderemos gerenciá-los corretamente e versão.\nMais informações podem ser encontradas aqui: [Wiki Go Modules] (https://github.com/golang/go/wiki/Modules)\n\nExemplo prático de como você irá proceder:\n\n```go\n$ go mod init github.com/user/project1\n```\n\n**Note**: \nQuando usarmos o go mod em $GOPATH, teremos que habilitar o uso de GO111MODULE=on, para que ele possa trabalhar dentro da estrutura $GOPATH.\n\nEntão, nosso programa pode compilar com sucesso.\n\n```go\n$ GO111MODULE=on go run cmd/main.go\n$ GO111MODULE=on go build -o project1 cmd/main.go\n```\n\n**Projeto fora do GOPATH e Local sem github**\n\nVamos criar nosso projeto sem github, somente local com nossos diretórios\n\n```bash\n$HOME/\n  |-codenation\n    |-project1\n      |-main.go\n      |-go.mod\n      |-pkg\n         |-math\n\t    - go.mod\n\t |-util\n\t    - go.mod\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n \nPercebe-se que temos go.mod agora no raiz e em cada pkg que desejamos configurar para que possamos importa-los.\n\nO arquivo go.mod na raiz ficaria assim:\n\n```go\nmodule project1\n\nrequire (\n\tpkg/math v0.0.0\n\tpkg/util v0.0.0\n)\n\nreplace (\n\tpkg/math =\u003e ./pkg/math\n\tpkg/util =\u003e ./pkg/util\n)\n\ngo 1.12\n```\n\nOs arquivos que encontra-se dentro de cada pacote ficaria assim:\npkg/math\n\n```go\nmodule math\n```\n\npkg/util\n\n```go\nmodule util\n```\nProntinho agora é testar\n\n```go\nGO111MODULE=on go run main.go\n```\n\n```go\nGO111MODULE=on go build main.go\n```\n\n## Instalação com Docker\n\nSe não quisermos instalar diretamente em nosso sistema operacional golang, podemos instalá-lo em um contêiner docker.\n\nPodemos carregar um contêiner docker com o idioma instalado e compilar e executar nossos programas a partir desse contêiner.\n\nVamos verificar como podemos fazer isso abaixo.\n\nMais informações e detalhes você pode visitar este link: [hub.docker] (https://hub.docker.com/_/golang)\n\n### Instalar Docker para Go\n\n```bash\n$ docker pull golang\n```\n\n### Compile seu aplicativo dentro do contêiner Docker\n\nPode haver ocasiões em que não é apropriado executar seu aplicativo em um contêiner. Para compilar, mas não executar seu aplicativo dentro da Instância do Docker, você pode escrever algo como:\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.12.4 go build -v\n```\n\nIsso adicionará seu diretório atual como um volume ao contêiner, configurará o diretório de trabalho para o volume e executará o comando go build, que informará para compilar o projeto no diretório de trabalho e exibir o executável em myapp. Como alternativa, se você tiver um Makefile, poderá executar o comando make dentro do contêiner.\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.12.4 make\n```\n\n### Cross-compile seu aplicativo dentro do contêiner Docker\nSe você precisar compilar seu aplicativo para uma plataforma diferente de linux/amd64 (como windows/386):\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp -e GOOS=windows \\\n-e GOARCH=386 golang:1.12.4 go build -v\n```\n\n#### Exemplo main.go\n\nVamos fazer nosso programa de testes, vamos chamar isso de main.go\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main(){\n\tfmt.Println(\"My first program being compiled by a docker container!\")\n}\n```\n\nAgora vamos rodar um programa para ver se funciona corretamente\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.12.4 go run main.go\n```\n\nSaída:\n\n```bash\nMy first program being compiled by a docker container!\n```\n\nConfira uma versão:\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.12.4 go versio\n```\n\nSaída:\n\n```bash\ngo version go1.12.4 linux/amd64\n```\n\n\n## Introdução Golang\n---\n\nGo é uma linguagem de propósito geral, projetada com a programação de sistemas em mente. É fortemente tipado e colecionador de lixo, e tem suporte explícito para programação concorrente. \nOs programas são construídos a partir de pacotes, cujas propriedades permitem o gerenciamento eficiente de dependências.\n\nA gramática é compacta e regular, permitindo fácil análise por ferramentas automáticas, como ambientes de desenvolvimento integrados.\n\n### Linguagem Golang\n---\n\n#### Keywords\n\nAs seguintes palavras-chave são reservadas e não podem ser usadas como identificadores:\n\n```bash\nbreak        default      func         interface    select\ncase         defer        go           map          struct\nchan         else         goto         package      switch\nconst        fallthrough  if           range        type\ncontinue     for          import       return       var\n```\n\n#### Operadores e Pontuação\n\nAs seqüências de caracteres a seguir representam operadores (incluindo operadores de atribuição) e pontuação: \n\n```bash\n+    \u0026     +=    \u0026=     \u0026\u0026    ==    !=    (    )\n-    |     -=    |=     ||    \u003c     \u003c=    [    ]\n*    ^     *=    ^=     \u003c-    \u003e     \u003e=    {    }\n/    \u003c\u003c    /=    \u003c\u003c=    ++    =     :=    ,    ;\n%    \u003e\u003e    %=    \u003e\u003e=    --    !     ...   .    :\n     \u0026^          \u0026^=\n```\n\n#### Println Print\n\nVamos aprender como enviar dados para a tela que é, na verdade, **stdout** saída padrão, veremos mais detalhes sobre  **stdout** e **stdin**.\n\nVamos conhecer **print, println and fmt.Println**\n\nAs implementações atuais fornecem várias funções internas úteis durante o bootstrapping. Essas funções são documentadas para integridade, mas não garantem a permanência na linguagem. Eles não retornam um resultado. \n\nRestrição de implementação: **print** e **println** não precisa aceitar tipos arbitrários de argumentos, mas a impressão de tipos boolean, numeric, e string types deve ser suportada. \n\n**println is an built-in function** (into the runtime) que pode eventualmente ser removido, enquanto o **fmt package** está na biblioteca padrão, que persistirá.\n\n```bash\nFunction   Behavior\n\nprint      prints all arguments; formatting of arguments is implementation-specific\nprintln    like print but prints spaces between arguments and a newline at the end\n```\n\nUsando Print:\n\n```go\n// test print\npackage main\n\nfunc main() {\n   print(\"debugging my system with print\")\n}\n```\n\nSaída:\n\n```bash\ndebugging my system with print\n```\n\nUsando println:\n\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"debugging my system with println\")\n}\n```\n\nSaída:\n\n```bash\ndebugging my system with println\n```\n\nUsando fmt.Println:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n   fmt.Println(\"debugging my system with fmt.Println\")\n}\n```\n\nSaída:\n\n```bash\ndebugging my system with fmt.Println\n```\n\nO objetivo de iniciar e executar o comando print, println ou fmt.Println é nos ajudar com os testes que faremos a partir de agora em todas as etapas do nosso aprendizado Go.\n\n\n#### Bufio NewWriter\n\n```bash\nbufio.Writer\n```\n\nFazer muitas gravações pequenas pode prejudicar o desempenho. Cada gravação é, em última instância, um syscall e se fazer com freqüência pode sobrecarregar a CPU. Dispositivos como discos funcionam melhor lidando com dados alinhados ao bloco. Para evitar a sobrecarga de muitas pequenas operações de gravação, o Golang é fornecido com o bufio.Writer. Os dados, em vez de ir diretamente para o destino (implementando a interface io.Writer) são acumulados primeiro dentro do buffer e enviados quando o buffer está cheio:\n\nVamos visualizar como o buffering funciona com nove gravações (um caractere cada) quando o buffer tem espaço para quatro caracteres:\n\n```bash\nproducer         buffer           destination (io.Writer)\n \n   a    -----\u003e   a\n   b    -----\u003e   ab\n   c    -----\u003e   abc\n   d    -----\u003e   abcd\n   e    -----\u003e   e      ------\u003e   abcd\n   f    -----\u003e   ef               abcd\n   g    -----\u003e   efg              abcd\n   h    -----\u003e   efgh             abcd\n   i    -----\u003e   i      ------\u003e   abcdefgh\n```\n\nConfira o exemplo abaixo:\n\n```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"os\"\n)\n\n// creating the write object pointer\n// so that we can receive value in every\n// scope of our program\nvar writer *bufio.Writer\n\nfunc main() {\n\t// All screen output will be redirected\n\t// to bufio.NewWriter\n\twriter = bufio.NewWriter(os.Stdout)\n\ts := \"How many stars does Orion have?\\n\"\n\tvar b byte = 'H'\n\n\twriter.WriteString(s)\n\twriter.WriteByte(b)\n\twriter.WriteString(\"\\n\")\n\n\t// when all the functions finishes it closes\n\t// the buffer and sends to the.Stdout\n\tdefer writer.Flush()\n}\n```\n\nSaída:\n\n```bash\nHow many stars does Orion have?\nH\n```\n\n#### Func Main\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Printf(\"hello, Gophers\\n\")\n}\n```\n\nEntão **build** com o **go tool**: \n\n```go\n$ cd $HOME/go/src/hello\n$ go build\n```\n\nOu podemos compilar assim:\n\n```go\n$ cd $HOME/go/src/hello\n$ go build -o hello hello.go\n```\n\nO comando acima irá construir um executável chamado hello no diretório ao lado do seu código-fonte. Execute para ver a saudação:\n\n```go\n$ ./hello\nhello, Gophers\n```\n\nVerifique também o comando **run** com o go: \n\n```go\n$ go run hello.go\nhello, Gophers\n```\n\nSe você ver o **\"hello, Gophers\"** mensagem, em seguida, sua instalação Go **is working**.\n\nVocê pode executar o **go install** para instalar o binário no diretório **bin** da sua área de trabalho ou **ir limpar -i** para removê-lo.\n\nExemplo: go install\n\n```go\n$ pwd\n$ $HOME/go/src/hello\n$ cd $HOME/go/src/hello\n$ go install\n$ ls -lhs $HOME/go/bin\n-rwxrwxr-x 1 user user 2,9M nov  8 03:11 hello\n```\n\nExample: go clean -i\n\n```go\n$ go clean -i \n$ ls -lhs $HOME/go/bin\n```\n\n## Comandos Go\n---\n\n### Introdução aos Comandos Go\n\nEm golang, temos um arsenal para nos ajudar quando se trata de compilar, testar, documentar, gerenciar perfis, etc.\n\n```bash\nbug         start a bug report\nbuild       compile packages and dependencies\nclean       remove object files and cached files\ndoc         show documentation for package or symbol\nenv         print Go environment information\nfix         update packages to use new APIs\nfmt         gofmt (reformat) package sources\ngenerate    generate Go files by processing source\nget         download and install packages and dependencies\ninstall     compile and install packages and dependencies\nlist        list packages or modules\nmod         module maintenance\nrun         compile and run Go program\ntest        test packages\ntool        run specified go tool\nversion     print Go version\nvet         report likely mistakes in packages\n```\n\nUse \"go help\" para mais informações sobre um comando.\n\n\n### Go Run\n---\n\nUso:\n\n```bash\ngo run [build flags] [-exec xprog] package [arguments...]\n```\n\nExecutar compila e executa o pacote principal chamado Go. Normalmente, o pacote é especificado como uma lista de arquivos de origem .go, mas também pode ser um caminho de importação, um caminho do sistema de arquivos ou um padrão que corresponda a um único pacote conhecido, como em 'go run .' ou 'go run my/cmd'.\n\nPor padrão, 'go run' executa o binário compilado diretamente: 'a.out arguments...'. se o sinalizador -exec for fornecido, 'go run' invoca o binário usando xprog:\n\nSe o sinalizador -exec não for fornecido, GOOS ou GOARCH será diferente do padrão do sistema, e um programa chamado go_ $ GOOS_ $ GOARCH_exec pode ser encontrado no caminho de busca atual, 'go run' invoca o binário usando esse programa, por exemplo, argumentos 'go_nacl_386_exec a.out...'. Isso permite a execução de programas compilados quando um simulador ou outro método de execução estiver disponível.\n\nO status de saída de Executar não é o status de saída do binário compilado.\n\nPara mais informações sobre sinalizadores de compilação, consulte 'go help build'. Para mais informações sobre como especificar pacotes, consulte 'go help packages'.\n\nVeja abaixo um exemplo:\n\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"Debugging my system with println\")\n}\n```\nGo run:\n\n```bash\ngo run println.go\n```\n\nSaída:\n\n```bash\nDebugging my system with println\n```\n\n### Go Build\n---\n\nBuild compila os pacotes nomeados pelos caminhos de importação, junto com suas dependências, mas não instala os resultados.\n\nAo compilar pacotes, o build ignora os arquivos que terminam em '_test.go'.\n\nO -o flag, permitido somente ao compilar um único pacote, obriga a compilação a gravar o executável ou objeto resultante no arquivo de saída nomeado, em vez do comportamento padrão descrito nos dois últimos parágrafos.\n\nO -i flag instala os pacotes que são dependências do destino.\n\n```go\n$ go build [-o output] [-i] [build flags] [packages]\n```\nVeja um exemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Println(\"Workshop Golang 2019.\")\n}\n```\n\nSaída:\n\n```bash\nWorkshop Golang 2019.\n```\n\nCompilação normal\n\n```go\ngo build -o hello hello.go\n```\n\nSaída:\n\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,9M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\nDeixando o arquivo menor após a compilação\n\n```go\ngo build -ldflags=\"-s -w\" hello.go\n```\n\nSaída:\n\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,3M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\n### Instalar Go \n---\n\nInstalar pacotes e dependências\n\nUso:\n\n```bash\n$ go install [-i] [build flags] [packages]\n```\n\nInstale compila e instala os pacotes nomeados pelos caminhos de importação.\n\nO **-i flag** instala as dependências dos pacotes nomeados também.\n\nPara mais sobre o build flags, confira 'go help build'. Para mais informações sobre como especificar pacotes, confira 'go help packages'.\n\n### Go Get\n---\n\nO **'go get'** comando muda o comportamento dependendo se o comando go está sendo executado no modo com reconhecimento de módulo ou no modo GOPATH herdado. Este texto de ajuda, acessível como 'go help module-get' mesmo em legado GOPATH mode, descreve 'go get' como opera em module-aware mode.\n\nUso:\n\n```bash\n$ go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]\n```\n\nObtenha downloads dos pacotes nomeados pelos caminhos de importação, junto com suas dependências. Em seguida, instale os pacotes nomeados, como 'go install'.\n\nVeja as bandeiras aceitas abaixo:\n\n```bash\nThe -d flag instructs get to stop after downloading the packages; that is, it instructs get not to install the packages.\n\nThe -f flag, valid only when -u is set, forces get -u not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.\n\nThe -fix flag instructs get to run the fix tool on the downloaded packages before resolving dependencies or building the code.\n\nThe -insecure flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP. Use with caution.\n\nThe -t flag instructs get to also download the packages required to build the tests for the specified packages.\n\nThe -u flag instructs get to use the network to update the named packages and their dependencies. By default, get uses the network to check out missing packages but does not use it to look for updates to existing packages.\n\nThe -v flag enables verbose progress and debug output.\n```\n\nExemplos:\n\n```bash\n$ go get -v github.com/guptarohit/asciigraph\n$ go get -u github.com/mxk/go-sqlite\n$ go get -v github.com/google/uuid\n$ go get -v github.com/sirupsen/logru\n```\n\n\n### Go Mod\n---\n\nUm módulo é uma coleção de pacotes Go relacionados. Módulos são a unidade de intercâmbio de código-fonte e controle de versão. O comando go tem suporte direto para trabalhar com módulos, incluindo gravação e resolução de dependências em outros módulos. Os módulos substituem a antiga abordagem baseada em GOPATH para especificar quais arquivos de origem são usados em uma determinada compilação.\n\nUso:\n\n```bash\n$ go mod \u003ccommand\u003e [arguments]\n```\nUm módulo é definido por uma árvore de arquivos de origem Go com um **go.mod** arquivo no diretório raiz da árvore. O diretório que contém o arquivo go.mod é chamado de raiz do módulo. Normalmente, a raiz do módulo também corresponderá a uma raiz de repositório de código-fonte (mas, em geral, não precisa). O módulo é o conjunto de todos os pacotes Go na raiz do módulo e em seus subdiretórios, mas excluindo subárvores com seus próprios arquivos go.mod.\n\nO \"module path\" é o prefixo do caminho de importação correspondente à raiz do módulo. O arquivo go.mod define o caminho do módulo e lista as versões específicas de outros módulos que devem ser usados ao resolver importações durante uma construção, fornecendo seus caminhos e versões de módulo.\n\nPor exemplo, este go.mod declara que o diretório que o contém é a raiz do módulo com o caminho example.com/m, e também declara que o módulo depende de versões específicas de golang.org/x/text and gopkg.in/yaml.v2: \n\n```bash\n$ go mod init github.com/user/gomyproject\n\nrequire (\n  golang.org/x/text v0.3.0\n  gopkg.in/yaml.v2 v2.1.0\n)\n```\nO arquivo go.mod também pode especificar substituições e versões excluídas que só se aplicam ao construir o módulo diretamente; eles são ignorados quando o módulo é incorporado em uma construção maior. Para mais informações sobre o arquivo go.mod, consulte 'go help go.mod'.\nPara iniciar um novo módulo, basta criar um arquivo go.mod na raiz da árvore de diretórios do módulo, contendo apenas uma instrução do módulo. O comando 'go mod init' pode ser usado para fazer isso:\n\n```bash\n$ go mod init github.com/user/gomyproject\n```\nEm um projeto que já utiliza uma ferramenta de gerenciamento de dependências existente como **godep, glide ou dep, 'go mod init'** também adicionará instruções requeridas que correspondam à configuração existente.\n\nUma vez que o arquivo go.mod existe, nenhuma etapa adicional é necessária: vá com comandos como **'go build'**, **'go test' **, ou até mesmo **'go list'** adicionará automaticamente novas dependências conforme necessário para satisfazer as importações.\n\nOs comandos são: \n\n```bash\ndownload    download modules to local cache\nedit        edit go.mod from tools or scripts\ngraph       print module requirement graph\ninit        initialize new module in current directory\ntidy        add missing and remove unused modules\nvendor      make vendored copy of dependencies\nverify      verify dependencies have expected content\nwhy         explain why packages or modules are needed\n```\nUse \"go help mod \u003ccommand\u003e\" para mais informações sobre um comando.\n\n\n### Go Mod Init\n\nInicializar novo módulo no diretório atual\n\nUso:\n\n```bash\n$ go mod init [module]\n```\n\nInit inicializa e grava um novo **go.mod** no diretório atual, na verdade, criar um novo módulo com raiz no diretório atual. O arquivo go.mod não deve existir. Se possível, o init irá adivinhar o caminho do módulo a partir dos comentários de importação (consulte 'go help importpath') ou da configuração do controle de versão. Para substituir essa suposição, forneça o caminho do módulo como um argumento.\n\n\n```bash\n$ go mod init github.com/user/gomyproject2\n\nrequire (\n  github.com/dgrijalva/jwt-go v3.2.0+incompatible\n  github.com/didip/tollbooth v4.0.0+incompatible\n  github.com/go-sql-driver/mysql v1.4.1\n  github.com/patrickmn/go-cache v2.1.0+incompatible // indirect\n  golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc\n  golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect\n)\n```\n\n### Go Mod Vendor\n\nO comando go mod mod vendor baixará todas as dependências para o diretório \"vendor\".\nAo usar o go mod mod, os pacotes não estão no seu diretório.\n\n```bash\n$ cd gomyproject2\n$ go mod vendor\n```\n\nSaída:\n\n```bash\n$ ls -lh vendor\ntotal 8,0K\ndrwxrwxr-x 3 root root 4,0K jan 27 01:47 github.com\n-rw-rw-r-- 1 root root  137 jan 27 01:47 modules.txt\n```\n\n### GO 1.11 Módulo\n\nGo 1.11 inclui suporte preliminar para os módulos Go, incluindo um novo comando 'go get' que reconhece os módulos. Nós pretendemos continuar revisando este suporte, preservando a compatibilidade, até que ele possa ser declarado oficial (não mais preliminar), e então, em um ponto posterior, podemos remover o suporte para o trabalho no GOPATH e o antigo comando 'go get'.\n\nA maneira mais rápida de aproveitar o novo suporte ao módulo Go 1.11 é verificar seu repositório em um diretório fora de GOPATH / src, criar um arquivo go.mod (descrito na próxima seção) e executar comandos go a partir desse arquivo árvore.\n\nPara um controle mais refinado, o suporte a módulos no Go 1.11 respeita uma variável de ambiente temporária, GO111MODULE, que pode ser definida como um dos três valores de string: off, on ou auto (o padrão). Se GO111MODULE = off, então o comando go nunca usa o novo suporte ao módulo. Em vez disso, ele procura nos diretórios de fornecedores e no GOPATH para localizar dependências; agora nos referimos a isso como \"modo GOPATH\". Se GO111MODULE = on, então o comando go requer o uso de módulos, nunca consultando o GOPATH. Nós nos referimos a isso como o comando sendo ciente do módulo ou em execução no \"modo de reconhecimento de módulo\". Se GO111MODULE = auto ou não estiver definido, o comando go ativa ou desativa o suporte a módulos com base no diretório atual. O suporte a módulos é ativado somente quando o diretório atual está fora de GOPATH / src e ele contém um arquivo go.mod ou está abaixo de um diretório contendo um arquivo go.mod\n\nNo modo ciente de módulo, GOPATH não define mais o significado de importações durante uma compilação, mas ainda armazena dependências baixadas (em GOPATH / pkg / mod) e comandos instalados (em GOPATH / bin, a menos que GOBIN esteja definido).\n\n\nConfira abaixo como usamos o comando:\n\n```bash\n$ GO111MODULE=on go run myprogram.go\n$ GO111MODULE=on go build myprogram.go\n```\nWhen our project is not in our **$GOPATH** it is not necessary to use **GO111MODULE**, but when our project is in **$GOPATH** and we want to use **\"go mod\"** we need to inform this to the compiler using **GO111MODULE**...\n\n\n### Go Test\n---\n\nPacotes de teste\n\nUso:\n\n```go\n$ go test [build/test flags] [packages] [build/test flags \u0026 test binary flags]\n```\n\nGo **test** automatiza o teste dos pacotes nomeados pelos caminhos de importação. Imprime um resumo dos resultados do teste no formato:\n\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nO pacote de teste é executado lado a lado com o comando go test. O teste de pacote deve ter o sufixo \"\\ _test.go\".\nPodemos dividir os testes em vários arquivos seguindo esta convenção. Por exemplo: \"myprog1_test.go\" and \"myprog2_test.go\".\n\nDevemos colocar nossas funções de teste nesses arquivos de teste.\n\nCada função de teste é uma função pública exportada cujo nome começa com **\"Test\"**, aceita um ponteiro para um objeto **testing.T** e não retorna nada. Como isso:\n\nExemplo 1 / myprog1_test:\n\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestWhatever(t *testing.T) {\n    // Your test code goes here\n}\n```\n\n```bash\n$ go test -v\n```\n\nSaída:\n\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nO objeto T fornece vários métodos que podemos usar para indicar falhas ou erros de log.\n\nExexmplo 2 / myprog2_test:\n\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  x := 1 + 1\n  if x != 11 { // forcing the error\n    t.Error(\"Error! 1 + 1 is not equal to 2, I got\", x)\n  }\n}\n```\n\n```bash\n$ go test -v\n```\n\nSaída:\n\n```bash\n=== RUN   TestSum\n-- FAIL: TestSum (0.00s)\n    myprog1_test.go:12: Error! 1 + 1 is not equal to 2, I got 2\nFAIL\nFAIL  command-line-arguments  0.001s\n```\n\nNeste exemplo, faremos uma examinação de como seria em nossos projetos.\n\nNeste programa vou passar parâmetro em tempo de compilação ou em nossa execução para facilitar e também servir como exemplo o uso de **\"ldflags\"** que podemos usar em **go run -ldflags** e **go build -ldflags**\n\nDe um check-in em nosso código abaixo / main.go:\n\n```go\nimport \"strconv\"\n\nimport (\n  \"github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math\"\n)\n\nvar (\n  x, y   string\n  xi, yi int\n)\n\nfunc init() {\n  xi, _ = strconv.Atoi(x)\n  yi, _ = strconv.Atoi(y)\n}\n\nfunc main() {\n  println(math.Sum(xi, yi))\n}\n```\n\nAgora temos uma função Soma em um pacote que criamos em **pkg/math/sum.go**\n\n```go\npackage math\n\nfunc Sum(x, y int) int {\n  return x + y\n}\n```\n\nCriamos nosso arquivo de teste em **pkg/math/sum_test.go**\n\n```go\npackage math\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  type args struct {\n    x int\n    y int\n  }\n  tests := []struct {\n    name string\n    args args\n    want int\n  }{\n    // TODO: Add test cases.\n    {\"test_1: \", args{2, 2}, 4},\n    {\"test_2: \", args{-2, 6}, 4},\n    {\"test_3: \", args{-4, 8}, 4},\n    {\"test_4: \", args{5, 7}, 12},\n    {\"test_5: \", args{8, 8}, 15}, // forcing the error\n  }\n  for _, tt := range tests {\n    t.Run(tt.name, func(t *testing.T) {\n      if got := Sum(tt.args.x, tt.args.y); got != tt.want {\n        t.Errorf(\"Sum() = %v, want %v\", got, tt.want)\n      }\n    })\n  }\n}\n```\n\n```bash\n$ cd pkg/math/\n$ go test -v\n```\n\nSaída:\n\n```bash\n=== RUN   TestSum\n=== RUN   TestSum/test_1:_\n=== RUN   TestSum/test_2:_\n=== RUN   TestSum/test_3:_\n=== RUN   TestSum/test_4:_\n=== RUN   TestSum/test_5:_\n--- FAIL: TestSum (0.00s)\n    --- PASS: TestSum/test_1:_ (0.00s)\n    --- PASS: TestSum/test_2:_ (0.00s)\n    --- PASS: TestSum/test_3:_ (0.00s)\n    --- PASS: TestSum/test_4:_ (0.00s)\n    --- FAIL: TestSum/test_5:_ (0.00s)\n        sum_test.go:29: Sum() = 16, want 15\nFAIL\nexit status 1\nFAIL  github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/pkg/math  0.001s\n```\n\nConverte para json a saída dos testes\n\n```bash\n$ go test -v -json\n```\n\nVerifique sua saída na tela do seu terminal para ver a saída do json.\n\n---\n\nAgora que salvamos nosso pkg / math / sum.go, vamos fazer um main.go fazendo a chamada neste pacote.\nMas primeiro vamos executar o go mod para gerenciar nossos pacotes e versões corretamente.\n\nVerifique o comando abaixo:\n\n```bash\n$ go mod init github.com/jeffotoni/goworkshopdevops/examples/tests/pkg\n```\n\nSaída:\n\n```bash\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples latest\ngo: finding github.com/jeffotoni/goworkshopdevops latest\ngo: downloading github.com/jeffotoni/goworkshopdevops v0.0.0-20190127023912-a2fa53299867\n0\n```\n\nAgora podemos fazer **build** ou **run** em nosso **main.go**.\n\nVamos rodar para rodar usando o flag **\"- ldflags\"** para passar parâmetros para o nosso código em tempo de compilação.\n\n```bash\n$ go run -ldflags \"-X main.x=2 -X main.y=3\" main.go\n```\n\nSaída:\n\n```bash\n5\n```\n\n```bash\n$ go run -ldflags \"-X main.x=7 -X main.y=3\" main.go\n```\n\nSaída:\n\n```bash\n10\n```\n\n## MÓDULO 02 Aprofundando na Linguagem\n---\n\n## Tipos\n---\n\nUm tipo determina um conjunto de valores junto com operações e métodos específicos para esses valores. Um tipo pode ser denotado por um nome de tipo, se tiver um, ou especificado usando um literal de tipo, que compõe um tipo de tipos existentes. \n\nA linguagem predeclara certos nomes de tipos. Outros são introduzidos com declarações de tipo. Tipos compostos -types—array, struct, pointer, function, interface, slice, map, e channel types—may- podem ser construídos usando literais de tipo.\n\nCada tipo T tem um tipo subjacente: Se T é um dos tipos boolean, numeric, ou string types, ou um type literal, o tipo subjacente correspondente é o próprio T. Caso contrário, o tipo subjacente de T é o tipo subjacente do tipo ao qual T se refere em sua declaração de tipo.\n\nExemplo:\n\n```bash\ntype (\n    A1 = string\n    A2 = A1\n)\n\ntype (\n    B1 string\n    B2 B1\n    B3 []B1\n    B4 B3\n)\n```\n\nO tipo subjacente de string, A1, A2, B1 e B2 é string. O tipo subjacente de [] B1, B3 e B4 é [] B1. \n\n\n### Numeric Types\n\nUm tipo numérico representa conjuntos de valores inteiros ou de ponto flutuante. Os tipos numéricos independentes da arquitetura pré-declarados são:\n\n```bash\nuint8       the set of all unsigned  8-bit integers (0 to 255)\nuint16      the set of all unsigned 16-bit integers (0 to 65535)\nuint32      the set of all unsigned 32-bit integers (0 to 4294967295)\nuint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)\n\nint8        the set of all signed  8-bit integers (-128 to 127)\nint16       the set of all signed 16-bit integers (-32768 to 32767)\nint32       the set of all signed 32-bit integers (-2147483648 to 2147483647)\nint64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)\n\nfloat32     the set of all IEEE-754 32-bit floating-point numbers\nfloat64     the set of all IEEE-754 64-bit floating-point numbers\n\ncomplex64   the set of all complex numbers with float32 real and imaginary parts\ncomplex128  the set of all complex numbers with float64 real and imaginary parts\n\nbyte        alias for uint8\nrune        alias for int32\n```\nO valor de um inteiro de n bits é n bits de largura e representado usando aritmética de complemento de dois.\n\nHá também um conjunto de tipos numéricos pré-declarados com tamanhos específicos de implementação:\n\n```bash\nuint     either 32 or 64 bits\nint      same size as uint\nuintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value\n```\n\nPara evitar problemas de portabilidade, todos os tipos numéricos são definidos e, portanto, distintos, exceto byte, que é um alias para uint8, e rune, que é um alias para int32. Conversões são necessárias quando diferentes tipos numéricos são misturados em uma expressão ou atribuição. Por exemplo, int32 e int não são do mesmo tipo, embora possam ter o mesmo tamanho em uma arquitetura específica.\n\n### String Types\n\nUm tipo de string representa o conjunto de valores de string. Um valor de string é uma seqüência (possivelmente vazia) de bytes. As strings são imutáveis: uma vez criadas, é impossível alterar o conteúdo de uma string. O tipo de string pré-declarado é string; é um tipo definido.\n\nO comprimento de uma string s (seu tamanho em bytes) pode ser descoberto usando a função interna len. O comprimento é uma constante de tempo de compilação se a string for uma constante. Os bytes de uma string podem ser acessados por índices inteiros de 0 a len (s) -1. É ilegal tomar o endereço de tal elemento; Se s [i] é o i'th byte de uma string, \u0026 s [i] é inválido.\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype S string\n\nvar (\n  String = \"@jeffotoni\"\n)\n\nfunc main() {\n  var text string\n  var str S\n\n  mypicture := \"@Photograph-jeffotoni\"\n  str = \"@workshop-devOpsBh\"\n  text = \"@jeffotoni-golang\"\n\n  fmt.Println(str)\n  fmt.Println(String)\n  fmt.Println(text)\n  fmt.Println(mypicture)\n\n  // example string\n  s := \"日本語\"\n  fmt.Printf(\"Glyph:             %q\\n\", s)\n  fmt.Printf(\"UTF-8:             [% x]\\n\", []byte(s))\n  fmt.Printf(\"Unicode codepoint: %U\\n\", []rune(s))\n}\n```\nSaída:\n\n```go\n@workshop-devOpsBh\n@jeffotoni\n@jeffotoni-golang\n@Photograph-jeffotoni\nGlyph:             \"日本語\"\nUTF-8:             [e6 97 a5 e6 9c ac e8 aa 9e]\nUnicode codepoint: [U+65E5 U+672C U+8A9E]\n```\n### Pointer Types\n\nCampos de estrutura podem ser acessados através de um ponteiro de estrutura.\n\nPara acessar o campo X de uma struct quando tivermos o struct pointer p poderíamos escrever (* p) .X. No entanto, essa notação é incômoda, de modo que a linguagem nos permite escrever apenas p.X, sem a referência explícita.\n\nUm tipo de ponteiro indica o conjunto de todos os ponteiros para variáveis de um determinado tipo, chamado tipo de base do ponteiro. O valor de um ponteiro não inicializado é nulo.\n\n```bash\nPointerType = \"*\" BaseType .\nBaseType    = Type .\n```\n\n```bash\n*Point\n*[4]int\n```\n\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{1, 2}\n  p := \u0026v\n  p.X = 1e9\n  fmt.Println(v)\n  fmt.Println(p.Y)\n}\n```\nSaída:\n\n```bash\n{1000000000 2}\n2\n```\nPara cada tipo declarado, seja por você ou pela própria linguagem, você obtém gratuitamente um tipo de ponteiro de complemento que você pode usar para compartilhar. Já existe um tipo embutido chamado int, então existe um tipo de ponteiro de complemento chamado * int.\n\nTodos os tipos de ponteiro possuem as mesmas duas características. Primeiro, eles começam com o personagem *. Segundo, todos eles têm o mesmo tamanho de memória e representação, que são 4 ou 8 bytes que representam um endereço. Em arquiteturas de 32 bits (como o playground), ponteiros exigem 4 bytes de memória e em arquiteturas de 64 bits (como sua máquina), eles exigem 8 bytes de memória.\n\nExemplo:\n\n```go\npackage main\n\nfunc main() {\n\n  var a int\n  inc := \u0026a\n  *inc = 2\n  *inc++\n  println(\"inc:\\tValue Of[\", inc, \"]\\tAddr Of[\", \u0026inc, \"]\\tValue Points To[\", *inc, \"]\")\n}\n```\n\nSaída:\n\n```bash\ninc:  Value Of[ 0xc000036778 ]  Addr Of[ 0xc000036780 ]  Value Points To[ 3 ]\n```\n\nPara um operando x do tipo T, a operação de endereço \u0026 x gera um ponteiro do tipo * T para x. O operando deve ser endereçável, isto é, uma variável, indicação indireta de ponteiro ou operação de indexação de fatia; ou um seletor de campo de um operável struct endereçável; ou uma operação de indexação de matriz de uma matriz endereçável. Como uma exceção ao requisito de endereçamento, x também pode ser um literal composto (possivelmente entre parênteses). Se a avaliação de x causar um pânico em tempo de execução, a avaliação de \u0026 x também ocorrerá.\n\nPara um operando x do tipo ponteiro * T, o indicador indireto * x denota a variável do tipo T apontada por x. Se x for nulo, uma tentativa de avaliar * x causará um pânico em tempo de execução.\n\n```bash\n\u0026x\n\u0026a[f(2)]\n\u0026Point{2, 3}\n*p\n*pf(x)\n\nvar x *int = nil\n*x   // causes a run-time panic\n\u0026*x  // causes a run-time panic\n```\n\nVeja o exemplo abaixo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  var a int = 100  /* actual variable declaration */\n  var pa *int      /* pointer variable declaration */\n  var pointer *int /* pointer variable declaration */\n\n  pa = \u0026a /* store address of a in pointer variable*/\n\n  fmt.Printf(\"Address of a variable: %x\\n\", \u0026a)\n\n  /* address stored in pointer variable */\n  fmt.Printf(\"Address stored in ip variable: %x\\n\", pa)\n\n  /* access the value using the pointer */\n  fmt.Printf(\"Value of *ip variable: %d\\n\", *pa)\n\n  /* succeeds if p is not nil */\n  if pa != nil {\n    fmt.Println(\"success is not nil\")\n  }\n\n  /* succeeds if p is null */\n  if (pointer) == nil {\n    fmt.Println(\"success pointer is nil\")\n  }\n}\n```\n\nSaída:\n\n```bash\nAddress of a variable: c0000160c8\nAddress stored in ip variable: c0000160c8\nValue of *ip variable: 100\nsuccess is not nil\nsuccess pointer is nil\n```\n\n### Array Types\n\nUma matriz é uma sequência numerada de elementos de um único tipo, denominada tipo de elemento. O número de elementos é chamado de comprimento e nunca é negativo.\n\n```bash\nArrayType   = \"[\" ArrayLength \"]\" ElementType .\nArrayLength = Expression .\nElementType = Type .\n```\n\nO comprimento é parte do tipo da matriz; deve avaliar a uma constante não negativa representável por um valor do tipo int. O comprimento do array a pode ser descoberto usando a função interna len. Os elementos podem ser endereçados pelos índices inteiros 0 a len (a) -1. Os tipos de matriz são sempre unidimensionais, mas podem ser compostos para formar tipos multidimensionais.\n\n```\n[32]byte\n[2*N] struct { x, y int32 }\n[1000]*float64\n[3][5]int\n[2][2][2]float64  // same as [2]([2]([2]float64))\n```\n\nO comprimento de uma matriz é parte do seu tipo, portanto, as matrizes não podem ser redimensionadas. Isso parece limitante, mas não se preocupe; Go fornece uma maneira conveniente de trabalhar com matrizes.\n\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n  // var a []string // wrong\n\n  // An array of 10 integers\n  var a1 [5]int\n  a1[0] = 5\n  a1[1] = 4\n  a1[2] = 3\n  a1[3] = 2\n  a1[4] = 1\n  fmt.Println(a1)\n}\n```\n\nSaída:\n\n```bash\n[5 4 3 2 1]\n```\n\n### Slice Types\n\nUma fatia é um descritor de um segmento contíguo de uma matriz subjacente e fornece acesso a uma seqüência numerada de elementos dessa matriz. Um tipo de fatia indica o conjunto de todas as fatias de matrizes de seu tipo de elemento. O valor de uma fatia não inicializada é nulo.\n\nUma matriz tem um tamanho fixo. Uma fatia, por outro lado, é uma visão flexível, de tamanho dinâmico, dos elementos de uma matriz. Na prática, as fatias são muito mais comuns que as matrizes.\n\nO tipo **[] T** é uma fatia com elementos de **type T**.\n\nUma fatia é formada especificando dois índices, um limite baixo e alto, separados por dois pontos:\n\n```bash\na[low : high]\n```\n\nIsso seleciona um intervalo half-open que inclui o primeiro elemento, mas exclui o último.\n\nA expressão a seguir cria uma fatia que inclui os elementos de 1 a 3 de um:\n\n```bash\na[1:4]\n```\n\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  primes := [7]int{2, 3, 5, 7, 11, 13, 14}\n  \n  var p []int = primes[2:5]\n  fmt.Println(p)\n}\n```\nSaída:\n\n```bash\n[5 7 11]\n```\n\nUm novo valor de fatia inicializado para um determinado tipo de elemento T é feito usando a função interna make, que usa um tipo de fatia e parâmetros que especificam o comprimento e, opcionalmente, a capacidade. Uma fatia criada com make sempre aloca uma nova matriz oculta à qual o valor da fatia retornada se refere. Isto é, executando.\n\n```bash\nmake([]T, length, capacity)\n```\n\nProduz a mesma fatia como alocar uma matriz e fatiá-la, então essas duas expressões são equivalentes:\n\n```bash\nmake([]int, 50, 100)\nnew([100]int)[0:50]\n```\n\nComo matrizes, as fatias são sempre unidimensionais, mas podem ser compostas para construir objetos de dimensões mais altas. Com matrizes de matrizes, as matrizes internas são, por construção, sempre o mesmo comprimento; no entanto, com fatias de fatias (ou conjuntos de fatias), os comprimentos internos podem variar dinamicamente. Além disso, as fatias internas devem ser inicializadas individualmente.\n\nFatias podem ser criadas com a função built-in make; É assim que você cria matrizes de tamanho dinâmico.\n\nA função make aloca uma matriz zerada e retorna uma fatia que se refere a essa matriz:\n\n```go\na := make([]int, 4)  // len(a)=4\n```\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  a := make([]int,4)\n  a[0]=12\n  fmt.Println(\"a\", a)\n\n  b := make([]int, 0, 5)\n  fmt.Println(\"b\", b)\n  \n  c := b[:2]\n  fmt.Println(\"c\", c)\n}\n```\nSaída:\n\n```bash\na [12 0 0 0]\nb []\nc [0 0]\n```\n\nUma fatia do tipo T é declarada usando [] T. Por exemplo, aqui está como você pode declarar uma fatia do tipo int -\n\n```go\n// Slice of type `int`\nvar slice []int\n\n// Slice of type `string`\nvar slice []string\n\n// Slice of type `string` with parameter variadic\nvar lang = [...]string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n```\n\nVocê pode criar uma fatia usando um literal de fatia como este -\n\n```go\n// Creating a slice using a slice literal\nvar s = []int{3, 5, 7, 9, 11, 13, 17}\n```\n\nA expressão do lado direito da declaração acima é um literal de fatia. O literal de fatia é declarado como um literal de matriz, exceto que você não especifica nenhum tamanho entre colchetes [].\n\nQuando você cria uma fatia usando um literal de fatia, ela primeiro cria uma matriz e, em seguida, retorna uma referência de fatia a ela.\n\nVamos ver:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar s = []string{\"@jeffotoni\", \"@awsbrasil\", \"@devopsbh\", \"@go_br\"}\n\n\t// Short hand declaration\n\tt := []int{2, 4, 8, 16, 32, 64}\n\n\tfmt.Println(\"s = \", s, len(s))\n\tfmt.Println(\"t = \", t, len(t))\n}\n```\nSaída:\n\n```bash\ns =  [@jeffotoni @awsbrasil @devopsbh @go_br] 4\nt =  [2 4 8 16 32 64] 6\n```\n\nComo uma fatia é um segmento de uma matriz, podemos criar uma fatia a partir de uma matriz.\n\nPara criar uma fatia de uma matriz a, especificamos dois índices baixo (limite inferior) e alto (limite superior) separados por dois pontos\n\n```bash\n// Obtaining a slice from an array `a`\na[low:high]\n```\n\nA expressão acima seleciona uma fatia da matriz a. A fatia resultante inclui todos os elementos, começando do índice baixo para o alto, mas excluindo o elemento no índice alto.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar groups = [5]string{\"@awsbrasil\", \"@devopsbh\", \"@go_br\", \"@devopsbr\", \"@docker\"}\n\n\t// Creating a slice from the array\n\tvar s []string = groups[2:5]\n\n\ts2 := s[1:3]\n\ts3 := s[:3]\n\ts4 := s[2:]\n\ts5 := s[:]\n\n\tfmt.Println(\"Array groups = \", groups, \"len:\", len(groups), \"cap:\", cap(groups))\n\tfmt.Println(\"Slice s = \", s, \"len:\", len(s), \"cap:\", cap(s))\n\tfmt.Println(\"Slice s = \", s2, \"len:\", len(s2), \"cap:\", cap(s2))\n\tfmt.Println(\"Slice s = \", s3, \"len:\", len(s3), \"cap:\", cap(s3))\n\tfmt.Println(\"Slice s = \", s4, \"len:\", len(s4), \"cap:\", cap(s4))\n\tfmt.Println(\"Slice s = \", s5, \"len:\", len(s5), \"cap:\", cap(s5))\n}\n```\n\nSaída:\n\n```bash\nArray groups =  [@awsbrasil @devopsbh @go_br @devopsbr @docker] len: 5 cap: 5\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@devopsbr @docker] len: 2 cap: 2\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@docker] len: 1 cap: 1\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\n```\n\nA função copy () copia elementos de uma fatia para outra. Sua assinatura se parece com isso:\n\n```go\nfunc copy(dst, src []T) int\n```\n\nSão necessárias duas fatias - uma fatia de destino e uma fatia de origem. Em seguida, copia elementos da origem para o destino e retorna o número de elementos copiados.\n\nObserve que os elementos são copiados somente se a fatia de destino tiver capacidade suficiente.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tsrc := []string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n\tdest := make([]string, 2)\n\n\tnumElementsCopied := copy(dest, src)\n\n\tfmt.Println(\"src = \", src)\n\tfmt.Println(\"dest = \", dest)\n\tfmt.Println(\"Number of elements copied from src to dest = \", numElementsCopied)\n}\n```\n\nSaída:\n\n```bash\nsrc =  [Erlang Elixir Haskell Clojure Scala]\ndest =  [Erlang Elixir]\nNumber of elements copied from src to dest =  2\n```\nA função append () acrescenta novos elementos no final de uma determinada fatia. A seguir, a assinatura da função append.\n\n```go\nfunc append(s []T, x ...T) []T\n```\n\nÉ preciso uma fatia e um número variável de argumentos x… T. Em seguida, ele retorna uma nova fatia contendo todos os elementos da fatia especificada, bem como os novos elementos.\n\nSe o segmento especificado não tiver capacidade suficiente para acomodar novos elementos, um novo array subjacente será alocado com maior capacidade. Todos os elementos da matriz subjacente da fatia existente são copiados para essa nova matriz e, em seguida, os novos elementos são anexados.\n\nNo entanto, se a fatia tiver capacidade suficiente para acomodar novos elementos, a função append () reutilizará sua matriz subjacente e anexará novos elementos à mesma matriz.\n\nVamos ver um exemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tslice1 := []string{\"Clojure\", \"Scala\", \"Elixir\"}\n\tslice2 := append(slice1, \"Assembly\", \"Rust\", \"Go\")\n\tfmt.Printf(\"slice1 = %v, len = %d, cap = %d\\n\", slice1, len(slice1), cap(slice1))\n\tfmt.Printf(\"slice2 = %v, len = %d, cap = %d\\n\", slice2, len(slice2), cap(slice2))\n\tslice1[0] = \"C++\"\n\tfmt.Println(\"\\nslice1 = \", slice1)\n\tfmt.Println(\"slice2 = \", slice2)\n\t\n\t// slice nil\n\tvar s []string\n\n\t// Appending to a nil slice\n\ts = append(s, \"Java\", \"C\", \"Lisp\", \"Haskell\")\n\tfmt.Printf(\"\\ns = %v, len = %d, cap = %d\\n\", s, len(s), cap(s))\n}\n```\n\nSaída:\n\n```bash\nslice1 = [Clojure Scala Elixir], len = 3, cap = 3\nslice2 = [Clojure Scala Elixir Assembly Rust Go], len = 6, cap = 6\n\nslice1 =  [C++ Scala Elixir]\nslice2 =  [Clojure Scala Elixir Assembly Rust Go]\n\ns = [Java C Lisp Haskell], len = 4, cap = 4\n```\n\n### Struct Types\n\nUma struct é uma sequência de elementos nomeados, chamados de campos, cada um com um nome e um tipo. Nomes de campos podem ser especificados explicitamente (IdentifierList) ou implicitamente (EmbeddedField). Dentro de uma estrutura, os nomes de campos não vazios devem ser exclusivos.\n\n```go\nStructType    = \"struct\" \"{\" { FieldDecl \";\" } \"}\" .\nFieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .\nEmbeddedField = [ \"*\" ] TypeName .\nTag           = string_lit .\n\n// An empty struct.\nstruct{}\n\n// A struct with 6 fields.\nstruct {\n  x, y int\n  u float32\n  _ float32  // padding\n  A *[]int\n  F func()\n}\n```\n\nUm campo declarado com um tipo, mas sem nome de campo explícito, é chamado de campo incorporado. Um campo incorporado deve ser especificado como um nome de tipo T ou como um ponteiro para um nome de tipo não-interface * T, e T em si não pode ser um tipo de ponteiro. O nome do tipo não qualificado atua como o nome do campo.\n\n```go\n// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4\nstruct {\n  T1        // field name is T1\n  *T2       // field name is T2\n  P.T3      // field name is T3\n  *P.T4     // field name is T4\n  x, y int  // field names are x and y\n}\n```\n\nA declaração a seguir é ilegal porque os nomes de campo devem ser exclusivos em um tipo de estrutura:\n\n```go\nstruct {\n  T     // conflicts with embedded field *T and *P.T\n  *T    // conflicts with embedded field T and *P.T\n  *P.T  // conflicts with embedded field T and *T\n}\n```\nUma estrutura é uma coleção de campos. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{10, 201}\n  v.X = 4\n  fmt.Println(v)\n}\n```\n\nSaída:\n\n```bash\n{4 201}\n```\n\n### Struct in C \n\nAntes de vermos a origem de tudo em C, vamos ver o código escrito em C e os comentários de como seria em Golang.\nE nós temos isso escrito em Golang, para que você possa ver como você estava dinâmico em Go, a herança C era simplesmente fantástica e leve.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\nstruct Login {\n    char *User;\n    char *Email;\n};\n\n/**\n  // In Go would look like this\n  type Login struct {\n    User string\n    Email string\n  }\n */\n\nint main() {\n/** \n // In Go \nfunc main() {\n*/\n    \n    struct Login login, *pointerToLogin;\n\n    /**\n    // In Go\n    login := Login{User:\"jeffotoni\", Email:\"jef@m.com\"}\n    */\n\n    login.User = \"jeffotoni\";\n    login.Email = \"jef@m.com\";\n\n    pointerToLogin = malloc(sizeof(struct Login));\n    pointerToLogin-\u003eUser = \"pike\";\n    pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    /**\n    var pointerToLogin  = new(Login)\n    pointerToLogin.User  = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n    */\n    printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    /**\n     fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n     fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email);\n    */\n\n    free(pointerToLogin);\n    return 0;\n}\n```\n\nCompile o programa em C:\n\n```\n$ gcc -o struct-1-c struct-1-c.c\n```\n\nSaída:\n\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: 0x5627788a0260 pike pike@g.com\n```\n\nConfira agora o Código em Go abaixo:\n\n```go\npackage main\n\nimport \"fmt\"\n// #include \u003cstdio.h\u003e\n// #include \u003cstdlib.h\u003e\n\n// struct Login {\n//     char *User;\n//     char *Email;\n// };\n\n//In Go would look like this\ntype Login struct {\n    User  string\n    Email string\n}\n\n// int main() {\n\n// In Go\nfunc main() {\n\n    //struct Login login, *pointerToLogin;\n\n    // In Go\n    login := Login{User: \"jeffotoni\", Email: \"jef@m.com\"}\n\n    login.User = \"jeffotoni\"\n    login.Email = \"jef@m.com\"\n\n    // pointerToLogin = malloc(sizeof(struct Login));\n    // pointerToLogin-\u003eUser = \"pike\";\n    // pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    var pointerToLogin = new(Login)\n    pointerToLogin.User = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n\n    //printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    //printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n    fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email)\n\n    //free(pointerToLogin);\n    return\n}\n```\n\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: \u0026{pike pike@g.com} pike pike@g.com\n```\n\n### Struct Type Tags Json\n\nUsamos tags json com omitempty ou não para representar nossa string json, quando geradas pelo **json.Marshal**, que veremos logo abaixo.\n\nExemplo:\n\n```go\nimport (\n\t//\"encoding/json\"\n\t\"fmt\"\n)\n\n// We use the omitempty tag in 'json: field, omitempty'\n// when we want the field not to appear after\n// making the marshal if it is empty.\ntype D struct {\n\tHeight int\n\tWidth  int `json:\"width,omitempty\"`\n}\n\n// Fields that do not have the \"omitempty\" tag will display \n// the same field being empty when generating \n// json through marshal.\ntype Cat struct {\n\tBreed    string `json:\"breed,omitempty\"`\n\tWeightKg int    `json:WeightKg`\n\tSize     D      `json:\"size,omitempty\"`\n}\n\nfunc main() {\n\td := Cat{\n\t\t//Breed:    \"Persa\",\n\t\tWeightKg: 23,\n\t\t//Size:     D{20, 60},\n\t}\n\t//b, _ := json.Marshal(d)\n\t//fmt.Println(string(b))\n\tfmt.Println(d)\n}\n```\n\nSaída:\n\n```bash\n{ 23 {20 60}}\n```\n\nNeste exemplo temos uma estrutura \"ApiLogin\" e dentro dela temos And1 \\ * struct \", ou seja, referenciando um ponteiro de outra struct, beautiful não é.\nPara inicializar e acessar o campo \"And1\", temos que usar o operador \"\u0026\" e criar a estrutura em sua inicialização, porque ela ainda não foi definida, então ficaria assim: **\"And1: \u0026 struct {City string} {City: \"BH\"}\"**\n```go\ntype ApiLogin struct {\n\tAnd1  *struct {\n\t\tCity string\n\t}\n}\n```\n\nNeste exemplo, só damos tempo ao ponteiro de uma estrutura já definida acima.\nPara acessá-lo não precisamos criá-lo novamente, basta se referir a ele com \"\u0026\" e assim \"And2: \u0026 Address {}\", muito legal, certo?\n\n```go\ntype ApiLogin struct {\n\tAnd2 *Address\n}\n```\n\nO exemplo abaixo é uma maneira de exibir várias formas de inicialização usando struct.\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Address struct {\n\tCity         string `json:\"city\"`\n\tNeighborhood string `json:\"neighborhood\"`\n\tZipcode      string `json:\"zipcode\"`\n}\n\ntype ApiLogin struct {\n\tName  string `json:\"name\"`\n\tCpf   string `json:\"cpf\"`\n\tLogin string `json:\"login\"`\n\tEmail string `json:\"email\"`\n\n\t// anonymous\n\tAnd1 *struct {\n\t\tCity string\n\t}\n\n\t// pointer\n\tAnd2 *Address\n\n\t// list Address\n\tAnd3 []Address\n}\n\nfunc main() {\n\n\t// different ways to inizialize a struct\n\t//\n\t//\n\n\tapilogin1 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}}\n\tfmt.Println(apilogin1)\n\tfmt.Println(apilogin1.Name)\n\tfmt.Println(apilogin1.And1)\n\tfmt.Println(apilogin1.And1.City)\n\n\tapilogin2 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin2)\n\tfmt.Println(apilogin2.Name)\n\tfmt.Println(apilogin2.And2)\n\tfmt.Println(apilogin2.And2.City)\n\n\tapilogin3 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}, And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin3)\n\tfmt.Println(apilogin3.Name)\n\tfmt.Println(apilogin3.And1)\n\tfmt.Println(apilogin3.And1.City)\n\tfmt.Println(apilogin3.And2)\n\tfmt.Println(apilogin3.And2.City)\n\n\tvar apilogin4 ApiLogin\n\tfmt.Println(apilogin4)\n\n\tapilogin5 := ApiLogin{}\n\tfmt.Println(apilogin5)\n\n\tapilogin6 := \u0026ApiLogin{}\n\tfmt.Println(apilogin6)\n\n\tapilogin7 := new(ApiLogin)\n\tfmt.Println(apilogin7)\n\n\t// another way to feed the struct\n\tg1add := Address{City: \"Belo Horizonte\"}\n\tg2add := Address{City: \"Curitiba\"}\n\n\t// declaring as list\n\tgall := []Address{}\n\n\t// add items\n\tgall = append(gall, g1add)\n\tgall = append(gall, g2add)\n\n\tfmt.Println(gall)\n\n\t// initializes Struct\n\tapil3 := ApiLogin{}\n\n\t// recive same type\n\tapil3.And3 = gall\n\n\t// show struct\n\tfmt.Println(apil3)\n\n\t// another way to initialize and feed the struct list\n\tapil3.And3 = []Address{{City: \"Sao Paulo\"}, {City: \"Brasilia\"}}\n\n\t// show struct\n\tfmt.Println(apil3)\n}\n```\n\nSaída:\n\n```bash\n\u0026{@jeffotoni 093.393.334-34   0xc00000e1e0 \u003cnil\u003e []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{@jeffotoni 093.393.334-34   \u003cnil\u003e 0xc000060150 []}\n@jeffotoni\n\u0026{BH  }\nBH\n\u0026{@jeffotoni 093.393.334-34   0xc00000e300 0xc0000601b0 []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{BH  }\nBH\n{    \u003cnil\u003e \u003cnil\u003e []}\n{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n[{Belo Horizonte  } {Curitiba  }]\n{    \u003cnil\u003e \u003cnil\u003e [{Belo Horizonte  } {Curitiba  }]}\n{    \u003cnil\u003e \u003cnil\u003e [{Sao Paulo  } {Brasilia  }]}\n```\n\nO exemplo abaixo é para demonstrar a facilidade que temos quando manipulamos estruturas em Golang.\nEstamos inicializando a estrutura com valores e exibindo na tela.\n\nDê uma olhada:\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype jsoninput []struct {\n\tData string `json:\"data\"`\n}\n\nfunc main() {\n\n\tdata := \u0026jsoninput{{Data: \"some data\"}, {Data: \"some more data\"},\n\t\t{Data: \"some more data\"}}\n\tfmt.Println(data)\n\n\t// output:\n\t//  \u0026[{some data} {some more data} {some more data}]\n}\n```\n\n```bash\n\u0026[{some data} {some more data} {some more data}]\n```\n\nEm nosso exemplo abaixo é outra maneira de fazer array de struct, fizemos a declaração no momento de inicializar nossa struct, isso faz com que a struct não seja pego apenas em aceitar array de struct.\nNós acrescentamos nos campos e a mágica acontece.\n\nVamos dar uma olhada no código completo:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n)\n\ntype User struct {\n\tFirstName string `tag_name:\"firstname\"`\n\tLastName  string `tag_name:\"lastname\"`\n\tAge       int    `tag_name:\"age\"`\n}\n\nfunc main() {\n\t// create instance\n\t// slice struct\n\tusers := []*User{}\n\n\tuser := new(User)\n\tuser.FirstName = \"Jefferson\"\n\tuser.LastName = \"otoni\"\n\tuser.Age = 350\n\tusers = append(users, user)\n\n\tuser = new(User)\n\tuser.FirstName = \"Pike\"\n\tuser.LastName = \"Hob\"\n\tuser.Age = 55\n\tusers = append(users, user)\n\n\tfmt.Println(users)\n\n\tfor k, v := range users {\n\t\tfmt.Println(k, v)\n\t\tfmt.Println(v.FirstName)\n\t\tfmt.Println(v.LastName)\n\t\tfmt.Println(v.Age)\n\t}\n}\n```\n\nSaída:\n\n```bash\n[0xc000060150 0xc000060180]\n0 \u0026{Jefferson otoni 350}\nJefferson\notoni\n350\n1 \u0026{Pike Hob 55}\nPike\nHob\n55\n```\n\nExemplo de estrutura AWS Sqs Json\n\n```go\ntype SqsJson struct {\n\tType      string `json:\"type\"`\n\tMessageId string `json:\"messageid\"`\n\tTopicArn  string `json:\"topicarn\"`\n\tMessage   string `json:\"message\"`\n\t//Message          JsonMessage\n\tTimestamp        string `json:\"timestamp\"`\n\tSignatureVersion string `json:\"signatureversion\"`\n\tSignature        string `json:\"signature\"`\n\tSigningCertURL   string `json:\"signingcerturl\"`\n\tUnsubscribeURL   string `json:\"unsubscribeurl\"`\n}\n\ntype JsonMessage struct {\n\tNotificationType string `json:\"notificationType\"`\n\tBounce           struct {\n\t\tBounceType        string `json:\"bounceType\"`\n\t\tBounceSubType     string `json:\"bounceSubType\"`\n\t\tBouncedRecipients []struct {\n\t\t\tEmailAddress   string `json:\"emailAddress\"`\n\t\t\tAction         string `json:\"action\"`\n\t\t\tStatus         string `json:\"status\"`\n\t\t\tDiagnosticCode string `json:\"diagnosticCode\"`\n\t\t} `json:\"bouncedRecipients\"`\n\t\tTimestamp    time.Time `json:\"timestamp\"`\n\t\tFeedbackID   string    `json:\"feedbackId\"`\n\t\tRemoteMtaIP  string    `json:\"remoteMtaIp\"`\n\t\tReportingMTA string    `json:\"reportingMTA\"`\n\t} `json:\"bounce\"`\n\n\tMail struct {\n\t\tTimestamp        time.Time `json:\"timestamp\"`\n\t\tSource           string    `json:\"source\"`\n\t\tSourceArn        string    `json:\"sourceArn\"`\n\t\tSourceIP         string    `json:\"sourceIp\"`\n\t\tSendingAccountID string    `json:\"sendingAccountId\"`\n\t\tMessageID        string    `json:\"messageId\"`\n\t\tDestination      []string  `json:\"destination\"`\n\t\tHeadersTruncated bool      `json:\"headersTruncated\"`\n\t\tHeaders          []struct {\n\t\t\tName  string `json:\"name\"`\n\t\t\tValue string `json:\"value\"`\n\t\t} `json:\"headers\"`\n\n\t\tCommonHeaders struct {\n\t\t\tFrom    []string `json:\"from\"`\n\t\t\tReplyTo []string `json:\"replyTo\"`\n\t\t\tTo      []string `json:\"to\"`\n\t\t\tSubject string   `json:\"subject\"`\n\t\t} `json:\"commonHeaders\"`\n\t} `json:\"mail\"`\n}\n```\n\nQuando o assunto é struct temos várias possibilidades de lidar e trabalhar com esse recurso em Golang, ele está praticamente embutido em tudo que vamos construir em Golang, Structs é algo poderoso em Go manipular dados e enviar dados o tempo todo entre canais usando goroutine, seja em filas, gravações de banco de dados, json e leituras de banco de dados, GraphQL, REST API, SOAP etc ...\n\n\n### Fatih Structs to Map\n\nAbaixo está uma biblioteca que trabalha diretamente com struct, convertendo para o Maps.\nEu não uso na produção, mas para o nosso curso é interessante analisar.\nSabemos que quanto mais nativos somos em Golang, será uma boa opção, mas às vezes precisaremos de algumas libs para nos ajudar.\nEste projeto não é mais mantido e é arquivado. Sinta-se à vontade para bifurcar e fazer suas próprias alterações, se necessário.\n\nStructs contém vários utilitários para trabalhar com estruturas Go (Golang). Ele foi inicialmente usado por mim para converter uma estrutura em uma interface {string] do mapa {}. Com o tempo, adicionei outros utilitários para estruturas. É basicamente um pacote de alto nível baseado em primitivas do pacote reflect. Sinta-se à vontade para adicionar novas funções ou melhorar o código existente.\n\nInstalar\n\n```go\ngo get github.com/fatih/structs\n```\n\nPara testar baixo, gire o código abaixo:\n\n```go\n\ntype Server struct {\n\tName        string `json:\"name,omitempty\"`\n\tID          int\n\tEnabled     bool\n\tUsers       []string // not exported\n\thttp.Server          // embedded\n}\n\nfunc main() {\n\n\t// Create a new struct type:\n\n\tserver := \u0026Server{\n\t\tName:    \"gopher\",\n\t\tID:      12345678,\n\t\tUsers:   []string{\"jeffotoni\", \"pike\", \"dennis\", \"ken\"},\n\t\tEnabled: true,\n\t}\n\n\t// struct\n\tfmt.Println(server)\n\n\t// create struct fatih\n\ts := structs.New(server)\n\tm := s.Map() // Get a map[string]interface{}\n\tfmt.Println(m)\n\n\tv := s.Values() // Get a []interface{}\n\tfmt.Println(v)\n\n\tf := s.Fields() // Get a []*Field\n\tfmt.Println(f)\n\n\tn := s.Names() // Get a []string\n\tfmt.Println(n)\n\n\tname := s.Field(\"Name\") // Get a *Field based on the given field name\n\n\t// Get the underlying value,  value =\u003e \"gopher\"\n\tvalue := name.Value().(string)\n\tfmt.Println(value)\n\n\ttagValue := name.Tag(\"json\")\n\tfmt.Println(tagValue)\n\n\tf1, ok := s.FieldOk(\"Name\") // Get a *Field based on the given field name\n\tfmt.Println(f1, ok)\n\n\tn2 := s.Name() // Get the struct name\n\tfmt.Println(n2)\n\n\th := s.HasZero() // Check if any field is uninitialized\n\tfmt.Println(h)\n}\n```\n\nSaída:\n\n```bash\n\u0026{gopher 12345678 true [jeffotoni pike dennis ken] \n{ \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e 0 0 {{0 0} 0} \u003cnil\u003e {0 0} map[] map[] \u003cnil\u003e []}}\nmap[Server:map[TLSConfig:\u003cnil\u003e ReadHeaderTimeout:0s IdleTimeout:0s Addr: Handler:\u003cnil\u003e \n]MaxHeaderBytes:0 TLSNextProto:map[] ConnState:\u003cnil\u003e ErrorLog:\u003cnil\u003e ReadTimeout:0s WriteTimeout:0s] \nName:gopher ID:12345678 Enabled:true Users:[jeffotoni pike dennis ken]]\n[gopher 12345678 true [jeffotoni pike dennis ken]  \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e]\n[0xc000106000 0xc000106090 0xc000106120 0xc0001061b0 0xc000106240]\n[Name ID Enabled Users Server]\ngopher\nname,omitempty\n\u0026{{0x626180 0xc0000f6000 408} {Name  0x626180 json:\"name,omitempty\" 0 [0] false} structs} true\nServer\ntrue\n```\n\n### Map Types\n\nUm mapa é um grupo não ordenado de elementos de um tipo, chamado de tipo de elemento, indexado por um conjunto de chaves exclusivas de outro tipo, chamado de tipo de chave. O valor de um mapa não inicializado é nulo.\n\n```bash\nMapType     = \"map\" \"[\" KeyType \"]\" ElementType .\nKeyType     = Type .\n```\n\nOs operadores de comparação == e! = Devem ser totalmente definidos para operandos do tipo de chave; Assim, o tipo de chave não deve ser uma função, mapa ou fatia. Se o tipo de chave for um tipo de interface, esses operadores de comparação devem ser definidos para os valores de chave dinâmica; falha causará um pânico em tempo de execução.\n\n```bash\nmap[string]int\nmap[*T]struct{ x, y float64 }\nmap[string]interface{}\n```\n\nO número de elementos do mapa é chamado seu comprimento. Para um mapa m, ele pode ser descoberto usando a função interna len e pode mudar durante a execução. Elementos podem ser adicionados durante a execução usando atribuições e recuperados com expressões de índice; eles podem ser removidos com a função integrada de exclusão.\n\nUm novo valor de mapa vazio é feito usando a função interna make, que usa o tipo de mapa e uma sugestão de capacidade opcional como argumentos:\n\n```bash\nmake(map[string]int)\nmake(map[string]int, 100)\n```\n\nA capacidade inicial não vincula seu tamanho: os mapas crescem para acomodar o número de itens armazenados neles, com exceção dos mapas nulos. Um mapa nulo é equivalente a um mapa vazio, exceto que nenhum elemento pode ser adicionado.\n\nAlguns exemplos de inicialização de mapa:\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype linkResult struct {\n\tbody string\n\turls []string\n}\n\ntype linkFetcher map[string]*linkResult\n\nfunc main() {\n\t// Required to initialize\n\t// the map with values\n\tvar m1 map[string]int\n\tvar m2 = make(map[string]int)\n\tvar m3 = map[string]int{\"population\": 500000}\n\tvar m4 = m3\n\tvar m5 map[string]string\n\t/* create a map*/\n\tm5 = make(map[string]string)\n\tfmt.Println(m1, m2, m3, m4, m5)\n\n\tvar l = linkFetcher{\n\t\t\"https://golang.org/\": \u0026linkResult{\n\t\t\t\"The Go Programming Language\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/pkg/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t},\n\t\t},\n\t\t\"https://golang.org/pkg/\": \u0026linkResult{\n\t\t\t\"Packages\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t\t\"https://golang.org/pkg/fmt/\",\n\t\t\t\t\"https://golang.org/pkg/os/\",\n\t\t\t},\n\t\t}}\n\n\tfmt.Println(l)\n}\n```\nSaída:\n\n```bash\nmap[] map[] map[population:500000] map[population:500000] map[]\n```\n\nUm mapa é declarado usando a seguinte sintaxe:\n\n```go\nvar m map[KeyType]ValueType\n\n// For example, Here is how you can declare a map of string keys to int values\nvar m map[string]int\n```\n\nO valor zero de um mapa é nulo. Um mapa nulo não possui chaves. Além disso, qualquer tentativa de adicionar chaves a um mapa nulo resultará em um erro de execução.\n\nVamos ver um exemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m map[string]int\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\t// Attempting to add keys\n\t// to a nil map will result in a runtime error\n\t//m[\"population\"] = 500000\n\t//fmt.Println(m)\n}\n```\n\nSaída:\n\n```bash\nmap[]\nis nil\n```\n\nVocê pode inicializar um mapa usando a função interna make (). Você só precisa passar o tipo do mapa para a função make () como no exemplo abaixo. A função retornará um mapa inicializado e pronto para uso.\n\n```go\n// Initializing a map using the built-in make() function\nvar m = make(map[string]int)\n```\n\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m = make(map[string]int)\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\tm[\"population\"] = 500000\n\tfmt.Println(m)\n}\n```\nSaída:\n\n```bash\nmap[]\nmap[population:500000]\n```\n\nO exemplo abaixo introduz a criação de um mapa obtendo um struct feito.\nQuando usamos uma estrutura vazia?\nExistem alguns cenários em que temos uma grande quantidade de acesso em nossa API, mas quando digo grande é\u003e 10k = 10k de solicitações por segundo, nesse cenário quando fazemos nosso manipulador, podemos implementar um canal recebendo uma estrutura vazia { } para que possamos colocar em um canal e processar tudo com mais segurança.\nMostraremos mais adiante esta abordagem muito legal.\n\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := \"key\"\n\tseen := make(map[string]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nSaída:\n\n```go\nmap[key:{}]\n```\nTambém podemos fazer com que nossa chave de mapa receba uma estrutura vazia.\nBem, nós sabemos que ele recebe qualquer tipo, ou seja, a estrutura pode ser completa sem que seja feita também.\n\nExemplo:\n\n```go\ntype T struct{}\n\nfunc main() {\n\ts := T{}\n\tseen := make(map[struct{}]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nSaída:\n\n```go\nmap[{}:{}]\n```\n\n### Map Literals Continued\n\nUm map literal é uma maneira muito conveniente de inicializar um mapa com alguns dados. Você só precisa passar os pares de valores-chave separados por dois pontos dentro de chaves.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar m = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\n\tfmt.Println(m)\n}\n```\n\nSaída:\n\n```bash\nmap[Italy:Roma France:Paris Japan:Toquio Brasil:Brasilia EUA:Washington, D.c]\n```\n\nAssim, você pode verificar a existência de uma chave em um mapa usando a seguinte atribuição de dois valores.\nA variável booleana ok será verdadeira se a chave existir e, caso contrário, será falsa.\n\n```go\nvalue, ok := m[key]\n```\n\nConsidere o seguinte mapa, por exemplo:\n\n```go\nvar C = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n```\n\n```go\ncapital, ok := C[\"EUA\"]  // \"Washington, D.c\", true\n```\n\nNo entanto, se você tentar acessar uma chave que não existe, o mapa retornará uma string vazia \"\" (valor zero de strings) e false\n\n```go\ncapital, ok := C[\"África do Sul\"]  // \"\", false\n```\nVocê pode excluir uma chave de um mapa usando a função integrada delete (). A sintaxe é assim.\n\n```go\n// Delete the `key` from the `map`\ndelete(map, key)\n```\nExemplo:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar country = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\tdelete(country, \"Japan\")\n\tdelete(country, \"Italy\")\n\tfmt.Println(country)\n}\n```\n\nSaída:\n\n```bash\nmap[Brasil:Brasilia EUA:Washington, D.c France:Paris]\n```\n \nSe o tipo de nível superior for apenas um nome de tipo, você poderá omiti-lo dos elementos do literal. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Login struct {\n\tUser, Login, Email string\n}\n\n// passing a struct as parameter\n// for our struct map\nvar m = map[string]Login{\n\t\"jeffotoni\": {\"jeffotoni\", \"jeff\", \"jeff@gm.com\"},\n\t\"Google\":    {\"root\", \"super\", \"google@gm.com\"},\n}\n\nfunc main() {\n\tfmt.Println(m)\n}\n```go\n\n```bash\nmap[jeffotoni:{jeffotoni jeff jeff@gm.com} Google:{root super google@gm.com}]\n```\n\n### Channel Types\n\nUm canal fornece um mecanismo para a execução simultânea de funções para comunicação, enviando e recebendo valores de um tipo de elemento especificado. O valor de um canal não inicializado é nulo.\n\n```bash\nChannelType = ( \"chan\" | \"chan\" \"\u003c-\" | \"\u003c-\" \"chan\" ) ElementType .\n```\n\nO operador \u003c- opcional especifica a direção do canal, enviar ou receber. Se nenhuma direção for dada, o canal é bidirecional. Um canal pode ser restrito apenas para enviar ou receber apenas por conversão ou atribuição.\n\n```bash\nchan T          // can be used to send and receive values of type T\nchan\u003c- float64  // can only be used to send float64s\n\u003c-chan int      // can only be used to receive ints\n```\nO operador \u003c- se associa ao canal mais à esquerda possível:\n\n```bash\nchan\u003c- chan int    // same as chan\u003c- (chan int)\nchan\u003c- \u003c-chan int  // same as chan\u003c- (\u003c-chan int)\n\u003c-chan \u003c-chan int  // same as \u003c-chan (\u003c-chan int)\nchan (\u003c-chan int)\n```\n\nUm novo valor de canal inicializado pode ser feito usando a função interna make, que aceita o tipo de canal e uma capacidade opcional como argumentos:\n\n```bash\nmake(chan int, 100)\n```\n\nA capacidade, em número de elementos, define o tamanho do buffer no canal. Se a capacidade for zero ou ausente, o canal não será buffer e a comunicação será bem-sucedida somente quando o remetente e o receptor estiverem prontos. Caso contrário, o canal é armazenado em buffer e a comunicação é bem-sucedida sem bloqueio se o buffer não estiver cheio (envia) ou não estiver vazio (recebe). Um canal nulo nunca está pronto para comunicação.\n\nUm canal pode ser fechado com a função interna fechada. O formulário de atribuição de valor múltiplo do operador de recebimento informa se um valor recebido foi enviado antes do canal ser fechado.\n\nA single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization. Channels act as first-in-first-out queues. Por exemplo, se uma goroutine enviar valores em um canal e uma segunda goroutine os receber, os valores serão recebidos na ordem enviada.\n\nDeixe-me mostrar-lhe um exemplo:\n\n```go\n\npackage main\n\nimport (\n  \"fmt\"\n  \"os\"\n  \"time\"\n)\n\ntype Promise struct {\n  Result chan string\n  Error  chan error\n}\n\nvar (\n  ch1  = make(chan *Promise)  // received a pointer from the structure\n  ch2  = make(chan string, 1) // allows only 1 channels\n  ch3  = make(chan int, 2)    // allows only 2 channels\n  ch4  = make(chan float64)   // has not been set can freely receive\n  ch5  = make(chan []byte)    // by default the capacity is 0\n  ch6  = make(chan bool, 1)   // non-zero capacity\n  ch7  = make(chan time.Time, 2)\n  ch8  = make(chan struct{}, 2)\n  ch9  = make(chan struct{})\n  ch10 = make(map[string](chan int)) // map channel\n  ch11 = make(chan error)\n  ch12 = make(chan error, 2)\n  // receives a zero struct\n  ch14 \u003c-chan struct{}\n  ch15 = make(\u003c-chan bool)          // can only read from\n  ch16 = make(chan\u003c- []os.FileInfo) // // can only write to\n  // holds another channel as its value\n  ch17 = make(chan\u003c- chan bool) // // can read and write to\n)\n\n// Parameters of Func\n// (jobs \u003c-chan int, results chan\u003c- int)\n\n// Receives Value, only read\n// jobs \u003c-chan int //receives the value\n\n// Receives Channel, only write\n// results chan\u003c- int // receive channel\n// or\n// results chan int // receive channel\n\n// Receives Channel variadic\n// results ...\u003c-chan int\n\nfunc main() {\n\n  ch2 \u003c- \"okay\"\n  defer close(ch2)\n  fmt.Println(ch2, \u0026ch2, \u003c-ch2)\n\n  ch7 \u003c- time.Now()\n  ch7 \u003c- time.Now()\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  defer close(ch7)\n\n  ch3 \u003c- 1 // okay\n  ch3 \u003c- 2 // okay\n  // deadlock\n  // ch3 \u003c- 3 // does not accept any more values, if you do it will error : deadlock\n  defer close(ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n\n  ch10[\"lambda\"] = make(chan int, 2)\n  ch10[\"lambda\"] \u003c- 100\n  defer close(ch10[\"lambda\"])\n  fmt.Println(\u003c-ch10[\"lambda\"])\n}\n```\n\nSaída:\n\n```bash\n0xc000056180 0x55bb00 okay\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906669 -0200 -02 m=+0.000147197\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906922 -0200 -02 m=+0.000147409\n0xc00001e0e0 0x55bb08 1\n0xc00001e0e0 0x55bb08 2\n100\n```\n\n### Blank Identifier\n\nO identificador em branco é representado pelo caractere de sublinhado **_**. Ele serve como um espaço reservado anônimo em vez de um identificador regular (non-blank) e tem um significado especial em declarações, como um operando e em atribuições.\n\nExemplo:\n\n```bash\n// function statement\nfunc f() (int, string, error)\n\n// function return\n_, _, _ := f()\n```\n\n### Tipos de interface\n\n**Uma interface são duas coisas:**\n - é um conjunto de métodos\n - mas também é um tipo\n\nO __interface {} type__, a interface vazia é a interface que tem __no métodos__\n\nComo não há nenhuma palavra-chave implements, todos os tipos implementam pelo menos zero métodos e a satisfação de uma interface é feita automaticamente, todos os tipos satisfazem a interface vazia.\nIsso significa que, se você escrever uma função que usa um valor {} de interface como um parâmetro, você poderá fornecer essa função com qualquer valor.\n\nExemplo:\n\n```go\nfunc DoSomething(v interface{}) {\n   // ...\n}\n\nvar Msg interface{}\n\ntype Stringer interface {\n    String() string\n}\n```\n\n#### Aqui está uma interface como um método\n\nUm tipo de interface especifica um conjunto de métodos chamado sua interface. Uma variável do tipo de interface pode armazenar um valor de qualquer tipo com um conjunto de métodos que seja qualquer superconjunto da interface. Tal tipo é dito para implementar a interface. O valor de uma variável não inicializada do tipo de interface é nulo.\n\n\n```bash\nInterfaceType      = \"interface\" \"{\" { MethodSpec \";\" } \"}\" .\nMethodSpec         = MethodName Signature | InterfaceTypeName .\nMethodName         = identifier .\nInterfaceTypeName  = TypeName .\n```\n\nComo com todos os conjuntos de métodos, em um tipo de interface, cada método deve ter um nome exclusivo não vazio.\n\n```go\n// A simple File interface\ninterface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n  Close()\n}\n```\n\nMais de um tipo pode implementar uma interface. Por exemplo, se dois tipos S1 e S2 tiverem o conjunto de métodos\n\n```bash\nfunc (p T) Read(b Buffer) bool { return … }\nfunc (p T) Write(b Buffer) bool { return … }\nfunc (p T) Close() { … }\n```\n\n(onde T significa S1 ou S2) então a interface File é implementada por S1 e S2, independentemente de quais outros métodos S1 e S2 possam ter ou compartilhar.\n\nUm tipo implementa qualquer interface que inclua qualquer subconjunto de seus métodos e, portanto, pode implementar várias interfaces distintas. Por exemplo, todos os tipos implementam a interface vazia:\n\n```bash\ninterface{}\n```\n\nDa mesma forma, considere esta especificação de interface, que aparece dentro de uma declaração de tipo para definir uma interface chamada Locker:\n\n```go\ntype Locker interface {\n  Lock()\n  Unlock()\n}\n```\n\nSe S1 e S2 também implementarem\n\n```bash\nfunc (p T) Lock() { … }\nfunc (p T) Unlock() { … }\n```\n\nEles implementam a interface do Locker, bem como a interface do arquivo.\n\nUma interface T pode usar um nome de tipo de interface (possivelmente qualificado) E no lugar de uma especificação de método. Isso é chamado de interface de incorporação E em T; adiciona todos os métodos (exportados e não exportados) de E para a interface T.\n\n```go\ntype ReadWriter interface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n}\n\ntype File interface {\n  ReadWriter  // same as adding the methods of ReadWriter\n  Locker      // same as adding the methods of Locker\n  Close()\n}\n\ntype LockedFile interface {\n  Locker\n  File        // illegal: Lock, Unlock not unique\n  Lock()      // illegal: Lock not unique\n}\n```\n\nUm tipo de interface T não pode incorporar a si mesmo ou a qualquer tipo de interface que incorpore T, recursivamente.\n\n```go\n// illegal: Bad cannot embed itself\ntype Bad interface {\n  Bad\n}\n\n// illegal: Bad1 cannot embed itself using Bad2\ntype Bad1 interface {\n  Bad2\n}\ntype Bad2 interface {\n  Bad1\n}\n```\n\nExemplo:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype R struct {\n  R string\n}\n\ntype Iread interface {\n  Read() string\n}\n\nfunc (r *R) Read() string {\n  return fmt.Sprintf(\"Only: call Read\")\n}\n\nfunc Call(ir Iread) string {\n  return fmt.Sprintf(\"Read: %s\", ir.Read())\n}\n\nfunc main() {\n  var iread Iread\n  r := R{\"hello interface\"}\n  // A way to use Interface\n  iread = \u0026r\n  fmt.Println(iread, r)\n  fmt.Println(iread.Read())\n\n  // Second way to access interface\n  r2 := R{\"hello interface call\"}\n  fmt.Println(Call(\u0026r2))\n}\n```\n\nSaída:\n\n```bash\n\u0026{hello interface} {hello interface}\nOnly: call Read\nRead: Only: call Read\n```\n\n####  Interface como tipo\n\nInterfaces como tipo __ interface {} __ significa que você pode colocar valor de qualquer tipo, incluindo seu próprio tipo personalizado. Todos os tipos em Go satisfazem uma interface vazia (interface {} é uma interface vazia).\nNo seu exemplo, o campo Msg pode ter valor de qualquer tipo.\n\n\n```go\nvar val interface{} // element type of m is assignable to val\n``` \n\n```go\ntype Empty interface {\n    /* it has no methods */\n}\n\n// Because, Empty interface has no methods, \n// following types satisfy the Empty interface\nvar a Empty\n\na = 60\na = 10.5\na = \"Lambda Man\"\n```\n\nInterfaces como tipos, veja outro exemplo abaixo:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype MyStruct struct {\n  Msg interface{}\n}\n\nfunc main() {\n  b := MyStruct{}\n  // string\n  b.Msg = \"5\"\n  fmt.Printf(\"%#v %T \\n\", b.Msg, b.Msg) // Output: \"5\" string\n\n  // int\n  b.Msg = 5\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n\n  // map\n  b.Msg = map[string]string{\"population\": \"500000\", \"language\": \"sueco\"}\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n}\n```\n\n### Exercício 1\n\nExercício:\nPreencha o struct JsonMessage AWS acima, inicialize a estrutura e preencha os campos, e faça um fmt.Println para exibir os campos preenchidos.\nPara ser mais legível, você pode separar em cada estrutura do tipo struct.\n\n## Estruturas de Controle\n---\n\n### Ao Controle\n\nAs estruturas de controle são:\n\n__For, If, else, else if__\n\nE algumas declarações entre elas: __break, continue, switch, case and goto__.\n\n#### Controle Return\n\nDeclarações controlam a execução.\n\n```bash\nStatement =\n  Declaration | LabeledStmt | SimpleStmt |\n  GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |\n  FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |\n  DeferStmt .\n\nSimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .\n```\n\nUma instrução final impede a execução de todas as instruções que aparecem lexicalmente após o mesmo bloco. As seguintes declarações estão terminando:\n\n1. Uma instrução \"return\" ou \"goto\".\n\nReturn:\n\n```go\npackage main\n\nfunc main() {\n  println(Lambda())\n  return\n}\n\nfunc Lambda() string {\n\n  return \"Lambda\"\n}\n```\n\nSaída:\n\n```bash\nLambda\n```\n\n#### Controle Goto\n\nGoto:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  n := 0\n\nLOOP1:\n  n++\n  if n == 10 {\n    println(\"fim\")\n    return\n  }\n\n  if n%2 == 0 {\n    goto LOOP2\n  } else {\n\n    fmt.Println(\"n\", n, \"LOOP1 here...\")\n    goto LOOP1\n  }\n\nLOOP2:\n  fmt.Println(\"n\", n, \"LOOP2 here...\")\n  goto LOOP1\n\n}\n```\n\nSaída:\n\n```bash\nn 1 LOOP1 here...\nn 2 LOOP2 here...\nn 3 LOOP1 here...\nn 4 LOOP2 here...\nn 5 LOOP1 here...\nn 6 LOOP2 here...\nn 7 LOOP1 here...\nn 8 LOOP2 here...\nn 9 LOOP1 here...\nfim\n```\n\n#### Control if Else\n\n2. Uma declaração \"if\" em que:\n      - a ramificação \"else\" está presente, e\n      - ambas as ramificações são declarações finais.\n      \n```go\npackage main\n\nfunc main() {\n  n := 100\n  if n \u003e 0 \u0026\u0026 n \u003c= 55 {\n    println(\"n \u003e 0 or n \u003c= 55\")\n  } else if n \u003e 56 \u0026\u0026 n \u003c 70 {\n    println(\"n \u003e 56 and n \u003c 70\")\n  } else {\n\n    if n \u003e= 100 {\n      println(\" else here.. n \u003e 100\")\n    } else {\n      println(\" else here.. n \u003e 70\")\n    }\n  }\n}\n```\n\nSaída:\n\n```bash\nelse here.. n \u003e 100\n```\n\n#### Control For Break Continue\n\n3. Uma declaração \"for\" em que:\n      - não há declarações de \"break\" referentes à declaração \"for\" e\n      - a condição de loop está ausente.\n      - existem \"continue\"\n      - Uma instrução \"break\"  termina a execução da instrução \"for\", \"switch\" ou \"select\" mais interna dentro da mesma\n\n```go\npackage main\n\nfunc main() {\n  // will be looping infinitely\n  // for {\n  // }\n\n  // will run only once and exit\n  for {\n    break\n  }\n\n  n := 5\n  for n \u003e 0 {\n    n--\n    println(n)\n  }\n  // Output:\n  // 4\n  // 3\n  // 2\n  // 1\n  // 0\n\n  // declaring i no and increasing i\n  for i := 0; i \u003c 5; i++ {\n    println(i)\n  }\n  // Output:\n  // 0\n  // 1\n  // 2\n  // 3\n  // 4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i \u003c= 2 {\n      continue\n    } else {\n      println(\"i \u003e 2 = \", i)\n    }\n  }\n\n  // Output:\n  // i \u003e 2 =  3\n  // i \u003e 2 =  4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i == 2 {\n      break\n    } else {\n      println(\"i: \", i)\n    }\n  }\n  // Output:\n  // i:  0\n  // i:  1\n  \n  // infinitely\n  for ; ; i++ {\n    println(\"i: \", i)\n  }\n  // Output:\n  // i:  1\n  // i:  2\n  // ..\n  // ..\n}\n```\n\n#### Control Switch Case Break\n\n4. Uma declaração \"switch\" em que:\n      - não há declarações de \"break\" referentes à declaração \"switch\",\n      -existe um \"case\" padrão e\n      - as listas de instruções em cada caso, incluindo o padrão, terminam em uma instrução final, ou uma declaração \"fallthrough\" possivelmente rotulada.\n\n```go\npackage main\n\nfunc main() {\n  j := 10\n  i := 0\n  switch j {\n  case 11:\n    println(\"here: 11\")\n    break\n  default:\n    println(\"here default\")\n    break\n  }\n\n  // infinitely\n  for ; ; i++ {\n\n    switch i {\n    case 5:\n      goto LABELS\n    case i:\n      println(\"i: \", i)\n      break\n    default:\n      println(\"default: \", i)\n    }\n  }\n\nLABELS:\n  f()\n\n}\n\nfunc f() {\n  println(\"goto fim\")\n}\n```\n\nSaída:\n\n```bash\nhere default\ni:  0\ni:  1\ni:  2\ni:  3\ni:  4\ngoto fim\n```\n\n#### Etiqueta de Controle\n\n5. Uma instrução rotulada rotulando uma instrução final.\n\n```go\npackage main\n\nfunc main() ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fcodenation.dev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffotoni%2Fcodenation.dev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fcodenation.dev/lists"}