---
title: "Go 1.14: Novidades e Recursos"
url: "https://golang.com.br/blog/go-1-14/"
markdown_url: "https://golang.com.br/blog/go-1-14.MD"
description: "Descubra as principais novidades do Go 1.14, incluindo novos recursos, melhorias de performance e mudancas na biblioteca padrao."
date: "2020-02-25"
author: "Golang Brasil"
---

# Go 1.14: Novidades e Recursos

Descubra as principais novidades do Go 1.14, incluindo novos recursos, melhorias de performance e mudancas na biblioteca padrao.


# Go 1.14: Um Olhar Detalhado nas Novidades

A versão 1.14 da linguagem Go foi lançada em 25 de fevereiro de 2020, trazendo consigo uma série de melhorias e adições que impactam tanto o desempenho quanto a usabilidade da linguagem. Esta versão foca em aprimorar o suporte a módulos, otimizar o desempenho do garbage collector e introduzir funcionalidades que facilitam o desenvolvimento concorrente. Este artigo explora as principais novidades, as mudanças na biblioteca padrão e fornece um guia prático para a atualização.

## Gerenciamento de Módulos Aprimorado

O Go 1.14 solidifica o suporte a módulos como o método padrão para gerenciamento de dependências. Embora os módulos tenham sido introduzidos em versões anteriores, o Go 1.14 remove a necessidade de configurar variáveis de ambiente como `GO111MODULE=on` para habilitar o uso de módulos fora do `$GOPATH`.  Agora, o Go assume que você está usando módulos se encontrar um arquivo `go.mod` no diretório atual ou em um diretório pai.

### Modo Vendor Ativado por Padrão

Uma das mudanças mais significativas é a ativação padrão do modo "vendor" quando um diretório `vendor` está presente no diretório raiz do módulo.  Isso significa que o Go irá procurar por dependências dentro do diretório `vendor` antes de recorrer ao cache de módulos globais ou a outros repositórios.

Essa mudança simplifica a reprodução de builds e garante que as dependências usadas durante o desenvolvimento sejam as mesmas usadas em produção. Para utilizar o modo vendor, basta ter um diretório `vendor` válido no seu projeto, criado geralmente através do comando `go mod vendor`.

```bash
go mod vendor
```

Após executar o comando, um diretório `vendor` será criado contendo todas as dependências declaradas no seu arquivo `go.mod`.  Durante a compilação, o Go irá priorizar os pacotes presentes neste diretório.

### Compatibilidade Aprimorada com Ferramentas de Terceiros

O Go 1.14 também introduz melhorias na compatibilidade com ferramentas de terceiros que interagem com os módulos Go. Essas melhorias visam facilitar a integração com IDEs, analisadores estáticos e outras ferramentas que dependem da análise da estrutura do módulo.

## Garbage Collector Mais Eficiente

O garbage collector (GC) do Go passou por otimizações significativas no Go 1.14, resultando em menor latência e maior utilização da CPU.  Essas melhorias são especialmente notáveis em aplicações com grandes quantidades de alocação e desalocação de memória.

### Coleta de Memória Não-Cooperativa

Uma das principais mudanças é a introdução da coleta de memória não-cooperativa.  Em versões anteriores, o GC dependia fortemente das goroutines para cooperar na coleta de memória.  No Go 1.14, o GC pode interromper as goroutines em pontos seguros para realizar a coleta de memória, reduzindo a latência e melhorando o desempenho geral.

Essa abordagem reduz a dependência da cooperação das goroutines e permite que o GC trabalhe de forma mais autônoma, especialmente em cenários onde algumas goroutines podem estar em execução por longos períodos sem liberar o processador.

### Melhorias na Escalonabilidade

O Go 1.14 também inclui melhorias na escalabilidade do GC em sistemas com muitos núcleos de CPU.  O GC agora consegue utilizar mais eficientemente os recursos disponíveis, resultando em menor tempo de pausa e maior taxa de transferência.

Essas melhorias beneficiam especialmente aplicações de alta performance que exigem baixa latência e alta escalabilidade.

## Goroutines Preemptivas Baseadas em Sinais

Uma das adições mais significativas no Go 1.14 é o suporte a goroutines preemptivas baseadas em sinais.  Essa funcionalidade resolve um problema de longa data na linguagem Go: goroutines que realizam loops infinitos ou operações de longa duração sem fazer chamadas de função podem bloquear o scheduler do Go, impedindo que outras goroutines sejam executadas.

### Resolvendo o Problema de Goroutines Bloqueadas

Em versões anteriores do Go, se uma goroutine entrasse em um loop infinito sem fazer chamadas de função (por exemplo, sem chamar `time.Sleep` ou enviar/receber dados em um canal), o scheduler do Go não conseguiria interromper essa goroutine para executar outras. Isso poderia levar a problemas de starvation, onde outras goroutines seriam impedidas de serem executadas.

O Go 1.14 introduz um mecanismo que permite ao scheduler enviar um sinal para uma goroutine que está em execução por um período prolongado sem fazer chamadas de função. Esse sinal força a goroutine a entrar em um ponto seguro, onde o scheduler pode interrompê-la e dar a outras goroutines a chance de serem executadas.

### Impacto no Desenvolvimento Concorrente

Essa mudança tem um impacto significativo no desenvolvimento concorrente em Go, tornando a linguagem mais robusta e previsível em cenários onde goroutines podem potencialmente bloquear o scheduler.

Embora essa funcionalidade seja ativada por padrão, ela ainda é considerada experimental e pode ser desabilitada através da variável de ambiente `GODEBUG=preemptoff=1`.  No entanto, a maioria dos usuários não precisa se preocupar em desativá-la, pois ela melhora a estabilidade e o desempenho do scheduler.

### Exemplo Prático

O exemplo abaixo demonstra como uma goroutine pode bloquear o scheduler em versões anteriores do Go e como o Go 1.14 resolve esse problema:

```go
package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	runtime.GOMAXPROCS(1) // Garante que apenas um núcleo seja usado
	go func() {
		for {
			// Loop infinito sem chamadas de função
		}
	}()

	time.Sleep(100 * time.Millisecond) // Espera um pouco para a goroutine iniciar

	fmt.Println("Hello from main!") // Esta linha pode não ser executada em versões anteriores do Go
}
```

Em versões anteriores do Go, a goroutine que contém o loop infinito pode impedir que a goroutine principal imprima "Hello from main!".  No Go 1.14, o scheduler consegue interromper a goroutine em loop e permitir que a goroutine principal seja executada.

## Mudanças na Biblioteca Padrão

O Go 1.14 também introduz algumas mudanças e adições à biblioteca padrão.

### Pacote `embed` (experimental)

O Go 1.14 introduz um novo pacote experimental chamado `embed`. Este pacote permite que arquivos sejam incorporados diretamente no executável Go durante a compilação. Isso é útil para incluir arquivos de configuração, templates HTML, arquivos estáticos e outros recursos que sua aplicação precisa.

Para usar o pacote `embed`, você precisa adicionar uma diretiva especial no seu código Go:

```go
//go:embed file.txt
var fileContent string
```

Neste exemplo, o conteúdo do arquivo `file.txt` será incorporado na variável `fileContent` durante a compilação.  O pacote `embed` oferece várias opções para trabalhar com arquivos e diretórios incorporados, incluindo a capacidade de iterar sobre os arquivos em um diretório.

**Exemplo:**

Suponha que você tenha um arquivo chamado `version.txt` com o número da versão do seu programa. Você pode incorporá-lo no seu código da seguinte forma:

```go
package main

import (
	"embed"
	"fmt"
)

//go:embed version.txt
var version string

func main() {
	fmt.Println("Version:", version)
}
```

Durante a compilação, o conteúdo do arquivo `version.txt` será incorporado na variável `version`.  Isso facilita a distribuição de aplicações com seus recursos incorporados.

**Considerações:**

*   O pacote `embed` é experimental e sua API pode mudar em versões futuras do Go.
*   A incorporação de arquivos grandes pode aumentar o tamanho do seu executável.

### Pacote `os/signal`

O pacote `os/signal` recebeu algumas melhorias para facilitar o tratamento de sinais do sistema operacional.

## Melhorias de Performance

Além das otimizações no garbage collector, o Go 1.14 também inclui outras melhorias de performance em diversas áreas da linguagem.

### Desempenho Aprimorado em Funções `defer`

A execução de funções `defer` foi otimizada, resultando em menor overhead e maior desempenho.  As funções `defer` são usadas para garantir que um bloco de código seja executado quando a função circundante retorna, independentemente de como a função retorna (normalmente ou devido a um panic).

### Otimizações no Inlining

O compilador Go agora realiza inlining de forma mais agressiva, substituindo chamadas de função por seu corpo diretamente no código.  Isso pode reduzir o overhead de chamadas de função e melhorar o desempenho geral.

## Como Atualizar para o Go 1.14

A atualização para o Go 1.14 é um processo relativamente simples.  Você pode baixar a nova versão do site oficial do Go ([https://go.dev/dl/](https://go.dev/dl/)) e seguir as instruções de instalação.

Após a instalação, você pode verificar se a atualização foi bem-sucedida executando o seguinte comando:

```bash
go version
```

Este comando deve imprimir a versão do Go instalada, confirmando que você está executando o Go 1.14.

### Considerações Importantes

*   **Teste seus projetos:** Antes de atualizar seus projetos para o Go 1.14 em produção, é importante testá-los exaustivamente para garantir que não haja problemas de compatibilidade.
*   **Verifique as dependências:** Certifique-se de que todas as suas dependências são compatíveis com o Go 1.14.  Se você estiver usando módulos Go, o comando `go mod tidy` pode ajudar a identificar e resolver problemas de dependência.
*   **Leia as notas de lançamento:** Consulte as notas de lançamento do Go 1.14 ([https://go.dev/doc/go1.14](https://go.dev/doc/go1.14)) para obter uma lista completa de todas as mudanças e correções.

## Conclusão

O Go 1.14 representa um avanço significativo na evolução da linguagem Go.  As melhorias no gerenciamento de módulos, no garbage collector e no scheduler tornam o Go uma linguagem ainda mais poderosa e eficiente para o desenvolvimento de aplicações modernas.  A introdução do pacote `embed` e outras mudanças na biblioteca padrão também facilitam o desenvolvimento e a distribuição de aplicações Go.  Ao atualizar para o Go 1.14, você pode se beneficiar dessas melhorias e garantir que seus projetos estejam usando a versão mais recente e otimizada da linguagem. A adoção dos módulos como padrão, juntamente com as melhorias de desempenho, solidificam o Go como uma escolha excelente para uma vasta gama de aplicações, desde microsserviços até ferramentas de linha de comando.
