---
title: "Go 1.16: Novidades e Recursos"
url: "https://golang.com.br/blog/go-1-16/"
markdown_url: "https://golang.com.br/blog/go-1-16.MD"
description: "Go 1.16 trouxe embed package (//go:embed), io/fs abstraction, suporte nativo Apple Silicon (M1), go install sem go.mod e modules on por padrao."
date: "2021-02-16"
author: "Golang Brasil"
---

# Go 1.16: Novidades e Recursos

Go 1.16 trouxe embed package (//go:embed), io/fs abstraction, suporte nativo Apple Silicon (M1), go install sem go.mod e modules on por padrao.


# Novidades do Go 1.16: Um Guia Detalhado

O Go 1.16, lançado em 16 de fevereiro de 2021, trouxe uma série de melhorias e novas funcionalidades que visam otimizar o desenvolvimento e a implantação de aplicações Go. Esta versão foca significativamente na incorporação de módulos, no aprimoramento do embedding de arquivos estáticos e em diversas melhorias na biblioteca padrão. Este artigo explora em detalhes as principais mudanças, oferecendo exemplos práticos e links para a documentação oficial.

## Incorporação de Arquivos Estáticos com `//go:embed`

Uma das adições mais notáveis do Go 1.16 é a diretiva `//go:embed`. Essa diretiva permite incluir arquivos e diretórios estáticos diretamente no binário Go durante a compilação. Anteriormente, era comum utilizar ferramentas externas ou soluções complexas para lidar com assets como templates HTML, arquivos JavaScript, CSS e imagens. Agora, o processo se torna muito mais simples e integrado.

### Funcionamento do `//go:embed`

A diretiva `//go:embed` é utilizada em conjunto com variáveis do tipo `string`, `[]byte` ou `embed.FS` (do novo pacote `embed`). A variável receberá o conteúdo do arquivo ou diretório especificado.

**Exemplo 1: Incorporando um arquivo de texto**

```go
package main

import (
	"fmt"
	_ "embed"
)

//go:embed hello.txt
var helloString string

func main() {
	fmt.Println(helloString)
}
```

Neste exemplo, o conteúdo do arquivo `hello.txt` será atribuído à variável `helloString` durante a compilação.  Para que isso funcione, é necessário que o arquivo `hello.txt` exista no mesmo diretório do arquivo `.go`.

**Exemplo 2: Incorporando um arquivo binário**

```go
package main

import (
	"fmt"
	_ "embed"
)

//go:embed logo.png
var logoBytes []byte

func main() {
	fmt.Printf("Tamanho da imagem: %d bytes\n", len(logoBytes))
}
```

Este exemplo demonstra a incorporação de um arquivo binário (uma imagem PNG) em um slice de bytes.

**Exemplo 3: Incorporando um diretório inteiro com `embed.FS`**

O pacote `embed` introduz o tipo `embed.FS`, que representa um sistema de arquivos incorporado (embedded file system). Isso permite trabalhar com diretórios inteiros de forma eficiente.

```go
package main

import (
	"embed"
	"fmt"
	"io/fs"
	"log"
	"net/http"
)

//go:embed static
var staticFS embed.FS

func main() {
	fsys, err := fs.Sub(staticFS, "static") // remove o prefixo "static"
	if err != nil {
		log.Fatal(err)
	}

	http.Handle("/", http.FileServer(http.FS(fsys)))
	fmt.Println("Servidor rodando na porta 8080")
	log.Fatal(http.ListenAndServe(":8080", nil))
}
```

Neste exemplo:

1.  `//go:embed static` incorpora o diretório `static` no sistema de arquivos `staticFS`.
2.  `fs.Sub(staticFS, "static")` cria um sub-sistema de arquivos removendo o prefixo "static", o que significa que a raiz do sistema de arquivos será o conteúdo dentro do diretório `static`. Isso é útil para evitar ter que referenciar `static/index.html` e, em vez disso, apenas `index.html`.
3.  `http.FileServer(http.FS(fsys))` cria um handler HTTP que serve os arquivos do sistema de arquivos incorporado.

Para este exemplo funcionar, crie um diretório chamado `static` no mesmo diretório do arquivo `.go`. Dentro de `static`, crie um arquivo `index.html` com algum conteúdo HTML.

### Vantagens do `//go:embed`

*   **Simplicidade:**  Elimina a necessidade de ferramentas de terceiros para o gerenciamento de assets.
*   **Portabilidade:**  Garante que todos os recursos necessários estejam incluídos no binário, facilitando a distribuição e a implantação.
*   **Desempenho:**  O acesso aos arquivos incorporados é geralmente mais rápido do que o acesso a arquivos em disco.

### Limitações do `//go:embed`

*   **Tamanho do binário:** A incorporação de arquivos aumenta o tamanho do binário executável.
*   **Imutabilidade:** Os arquivos incorporados são imutáveis e não podem ser modificados em tempo de execução.
*   **Restrições de caminho:** Os caminhos especificados na diretiva `//go:embed` devem ser relativos ao diretório do arquivo Go que contém a diretiva.

Documentação oficial: [https://go.dev/pkg/embed](https://go.dev/pkg/embed)

## Melhorias no Módulo Go

O Go 1.16 continua a fortalecer o suporte a módulos, tornando-os a forma padrão de gerenciamento de dependências.  Esta versão introduz o comportamento padrão de habilitar os módulos e simplifica ainda mais o processo de desenvolvimento com módulos.

### Habilitando Módulos por Padrão

A partir do Go 1.16, os módulos são habilitados por padrão. Isso significa que, a menos que explicitamente desativado, o Go tentará utilizar módulos para gerenciar as dependências do seu projeto. Isso elimina a necessidade de definir a variável de ambiente `GO111MODULE=on` na maioria dos casos.

### `go install` com Módulos

O comando `go install` agora funciona de forma mais consistente com módulos. Anteriormente, o `go install` poderia instalar pacotes no `$GOPATH/bin`, o que poderia levar a confusão. No Go 1.16, o `go install` instala pacotes no `$GOBIN` (ou `$GOPATH/bin` se `$GOBIN` não estiver definido) quando estiver fora de um módulo ou quando o módulo atual não usa módulos (ou seja, tem `GO111MODULE=off`). Quando dentro de um módulo que usa módulos, `go install` sempre instala pacotes no cache do módulo, e o executável não é colocado no `$GOBIN` ou `$GOPATH/bin`.

Para instalar um executável de um módulo diretamente no `$GOBIN`, use o comando `go install nome_do_modulo@versao`. Por exemplo, para instalar a versão mais recente da ferramenta `golangci-lint` no seu `$GOBIN`, você pode executar:

```bash
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
```

### `go mod tidy`

O comando `go mod tidy` foi aprimorado para remover dependências não utilizadas com mais precisão e adicionar dependências ausentes. É uma prática recomendada executar `go mod tidy` regularmente para manter seu arquivo `go.mod` limpo e preciso.

### `go mod vendor`

O comando `go mod vendor` copia as dependências do seu projeto para o diretório `vendor`. Embora o uso do diretório `vendor` não seja mais necessário na maioria dos casos (já que o Go busca dependências diretamente do cache do módulo), ele ainda pode ser útil em alguns cenários, como quando você precisa construir seu projeto em um ambiente sem acesso à internet.

### Considerações sobre Módulos

*   Certifique-se de ter um arquivo `go.mod` na raiz do seu projeto. Se você não tiver um, pode criá-lo com o comando `go mod init nome_do_modulo`.
*   Utilize o comando `go get` para adicionar ou atualizar dependências. Por exemplo, `go get github.com/gorilla/mux@v1.8.0` adiciona ou atualiza a dependência `github.com/gorilla/mux` para a versão `v1.8.0`.
*   Verifique regularmente as atualizações de dependências com `go list -m -u all`.

Documentação oficial: [https://go.dev/ref/mod](https://go.dev/ref/mod)

## Melhorias na Biblioteca Padrão

O Go 1.16 introduz diversas melhorias e adições à biblioteca padrão, incluindo novos pacotes e funcionalidades aprimoradas em pacotes existentes.

### Novo Pacote `io/fs`

O pacote `io/fs` define interfaces para um sistema de arquivos, fornecendo uma abstração para interagir com arquivos e diretórios de forma genérica.  É usado em conjunto com o pacote `embed` para trabalhar com sistemas de arquivos incorporados.

Interfaces chave no pacote `io/fs`:

*   `fs.FS`: Interface básica para um sistema de arquivos.
*   `fs.File`: Interface para um único arquivo.
*   `fs.DirEntry`: Interface para uma entrada de diretório (um arquivo ou diretório).

### Melhorias no Pacote `net/http`

O pacote `net/http` recebeu várias melhorias, incluindo:

*   **Suporte a HTTP/2 por padrão:**  O suporte a HTTP/2 é habilitado por padrão, melhorando o desempenho e a eficiência das aplicações web.
*   **Novas opções de configuração:**  Novas opções de configuração foram adicionadas para permitir um controle mais granular sobre o comportamento do servidor HTTP.

### Outras Melhorias

*   **Pacote `runtime/metrics`:**  Adição de um pacote para expor métricas detalhadas do runtime do Go.
*   **Pacote `sync/atomic`:**  Melhorias de desempenho em operações atômicas em algumas arquiteturas.

## Melhorias de Performance

Embora o Go 1.16 não apresente mudanças drásticas em termos de performance, várias otimizações e melhorias incrementais foram implementadas, resultando em ganhos de desempenho sutis em diversas áreas.

*   **Melhorias no Garbage Collector:**  Otimizações contínuas no Garbage Collector (GC) contribuem para reduzir a latência e melhorar o uso da memória.
*   **Otimizações no compilador:**  Melhorias no compilador resultam em código mais eficiente e tempos de compilação reduzidos.
*   **Melhorias no pacote `sync/atomic`:**  Operações atômicas foram otimizadas para algumas arquiteturas, resultando em melhor desempenho em aplicações que fazem uso intensivo de concorrência.

## Como Atualizar para o Go 1.16

A atualização para o Go 1.16 é um processo simples e direto. Você pode utilizar as ferramentas oficiais de gerenciamento de versões do Go para realizar a atualização.

1.  **Verifique a versão atual do Go:**

    ```bash
    go version
    ```

2.  **Utilize `go install` para instalar a versão mais recente:**

    ```bash
    go install golang.org/dl/go1.16@latest
    go1.16 download
    go1.16 use
    ```

    Este comando baixa e instala o Go 1.16 e o define como a versão padrão.

3.  **Verifique a versão após a atualização:**

    ```bash
    go version
    ```

    A saída deve indicar que você está utilizando o Go 1.16.

4.  **Atualize suas dependências:**

    Após a atualização, execute o comando `go mod tidy` para garantir que suas dependências estejam atualizadas e corretas.

## Conclusão

O Go 1.16 representa um passo significativo na evolução da linguagem, com foco na melhoria da experiência do desenvolvedor e na otimização do processo de desenvolvimento e implantação. A incorporação de arquivos estáticos com `//go:embed`, as melhorias no suporte a módulos e as adições à biblioteca padrão tornam o Go 1.16 uma versão altamente recomendada para todos os desenvolvedores Go. Ao adotar as novas funcionalidades e otimizações, você pode simplificar seu fluxo de trabalho, melhorar o desempenho de suas aplicações e aproveitar ao máximo o ecossistema Go.

Documentação oficial completa do Go 1.16: [https://go.dev/doc/go1.16](https://go.dev/doc/go1.16)
