O Go 1.16, a 17ª versão principal da linguagem de programação Go, acaba de ser lançado. É uma atualização significativa que traz muitos recursos e refinamentos há muito esperados para a linguagem. O modo com reconhecimento de módulo é habilitado por padrão, o suporte a silício da Apple está ativo, a incorporação nativa de ativos estáticos está aqui e os métodos no pacote  io/ioutil  foram reorganizados para que agora faça sentido lógico. Neste artigo, daremos uma olhada em alguns dos destaques desta versão. 
Suporte nativo para silício Apple
Desde o seu início, Go priorizou a portabilidade entre diferentes sistemas operacionais e arquiteturas e isso se reflete em seu suporte para uma ampla variedade de sistema operacional e combinações de arquitetura .
 Nos últimos meses, o lançamento do primeiro ARM Mac de 64 bits da Apple foi um dos tópicos mais dominantes entre os desenvolvedores devido ao seu salto impressionante no desempenho de CPU, GPU e bateria. O projeto Go respondeu prontamente adicionando suporte nativo para ARM Macs por meio das variáveis ambientais  GOOS=darwin  e  GOARCH=arm64 . 
Se você tiver um Mac M1, agora poderá criar e executar programas Go nativamente em seu computador e, se estiver em um sistema operacional diferente ou em um Mac baseado em Intel, pode direcionar Macs ARM por definindo as variáveis ambientais acima ao construir o binário para seu programa:
GOARCH=arm64 GOOS=darwin vá construir meu aplicativo
Incorporação nativa de arquivos estáticos
 Uma das melhores coisas sobre Go é que programas compilados podem ser distribuídos e executados como um único arquivo binário livre de dependência. Esta vantagem é um pouco compensada quando um programa depende de arquivos estáticos, como modelos HTML, arquivos de migração de banco de dados, ativos de aplicativos da web como JavaScript ou arquivos de imagens como esses arquivos, muitas vezes precisam ser distribuídos com o binário, a menos que sejam incorporados ao binário a ajuda de um pacote de terceiros, como  pkger  ou  packr . Com o lançamento do Go 1.16, agora é possível incluir nativamente arquivos estáticos em um binário Go por meio do novo pacote  embed . 
 Este é o exemplo mais básico de como esse recurso funciona. Supondo que você tenha um arquivo  sample.txt  cujo conteúdo é mostrado abaixo: 
Olá do arquivo de texto
 E um arquivo  main.go  no mesmo diretório com o seguinte conteúdo: 
 pacote principal importar ( _"Embutir" "fmt"
) //go: embed sample.txt
var string de texto func main () { fmt.Print (texto)
}
 A diretiva  go: embed  colocada acima da variável  text  instrui o compilador a incorporar o conteúdo do arquivo  sample.txt  como uma string na variável  text . Se você construir o programa com  go build  e mover o binário resultante para um local diferente, você notará que executá-lo imprimirá o conteúdo do arquivo embutido na saída padrão. Isso ocorre porque todo o conteúdo do arquivo  sample.txt  foi incluído dentro do binário para que possa ser distribuído como está: 
$ mv main/tmp $ cd/tmp $./main Olá do arquivo de texto
Para um exemplo mais realista, digamos que temos um projeto de aplicativo da web com a seguinte estrutura de diretório:
. ├── ativos │ ├── css │ │ └── style.css │ └── js │ └── script.js ├── go.mod ├── index.html ├── main.go └── aleatório
 Podemos incorporar todos os arquivos na pasta  assets  e no arquivo  index.html  assim: 
 pacote principal importar ( "Embutir" "net/http"
) //go: embed assets/*
var assets embed.FS //go: embed index.html
var html [] byte func main () { fs:=http.FileServer (http.FS (ativos)) http.Handle ("/ativos/", fs) http.HandleFunc ("/", func (w http.ResponseWriter, r * http.Request) { w.Header (). Adicionar ("Content-Type","text/html") w.Write (html) }) http.ListenAndServe (": 8080", nulo)
}
 O tipo  FS  é útil para incorporar uma árvore de arquivos, como um diretório de ativos de servidor da web, como no exemplo acima. Para incorporar um único arquivo como  index.html , uma variável do tipo  string  ou  [] byte  é melhor. Se você construir e executar o programa e navegar até  http://localhost: 8080 , verá o conteúdo do arquivo HTML com os ativos estáticos aplicados corretamente: 
versão $ go go versão go1.16rc1 linux/amd64 $ go build-o main $ mv main/tmp $ cd/tmp &&./main
  
Você pode baixar o conteúdo de index.html , style.css e script.js arquivo se desejar executar o exemplo localmente. Para obter mais detalhes, consulte a documentação para o novo pacote embed.
Algumas pegadinhas
 Antes de usar a diretiva //go: embed , você deve importar o pacote  embed . Caso contrário, você obterá um erro: 
$ go run main.go # argumentos da linha de comando ./main.go:8:3://go: embed permitido apenas em arquivos Go que importam"embed"
 Se você não estiver usando nenhuma identificação exportada diretamente de  embed , certifique-se de prefixar a instrução de importação com um sublinhado: 
import ( _"Embutir" )
 Outra coisa a se estar ciente é que //go: embed  funciona apenas em variáveis de nível de pacote. Se você tentar usá-lo dentro de uma função, seu código não compilará: 
 pacote principal importar ( _"Embutir" "fmt"
) func main () { //vá: embed index.html var string html fmt.Println (html)
}
$ go run main.go # argumentos da linha de comando ./main.go:9:4: go: embed não pode ser aplicado a var dentro de func
O modo com reconhecimento de módulo é habilitado por padrão
 A introdução dos  módulos Go  em  Go 1.11  anunciou um afastamento da semântica  GOPATH  para gerenciamento de dependências. Nessa versão inicial e  Go 1.12 , os módulos ainda eram experimentais e tinham que ser ativado com a variável de ambiente  GO111MODULE=on .  Go 1.13  garantiu que o modo com reconhecimento de módulo fosse ativado automaticamente sempre que um  O arquivo go.mod  está presente no diretório de trabalho atual ou em um diretório pai, mesmo se o diretório estiver dentro do  GOPATH  e este permaneceu o caso em  Go 1.14  e  1,15 . 
 Com o lançamento do Go 1.16, a variável  GO111MODULE  agora é padronizada como  on , o que significa que o modo com reconhecimento de módulo está habilitado por padrão, independentemente de um  go O arquivo.mod  está presente no diretório atual. Se você deseja reverter para o comportamento anterior, defina  GO111MODULE  como  auto . 
 Em outras alterações relacionadas,  go build  e  go test  não modificarão mais o  go.mod  e  go.sum  arquivos por padrão. Em vez disso, um erro será relatado se um requisito de módulo ou soma de verificação precisar ser adicionado ou atualizado. Você pode então usar  go mod tidy  ou  go get  para ajustar os requisitos de acordo. 
 O comando  go install  agora também reconhece o módulo, o que significa que não afetará o arquivo  go.mod  no diretório atual ou em qualquer diretório pai, se há um. Além disso, agora ele pode receber um número de versão como sufixo. Por exemplo: 
$ go install github.com/[email protected]
 No Go 1.16, o uso de  go get  para construir e instalar pacotes foi descontinuado em favor de  go install . Em uma versão futura,  go get  não será mais capaz de construir e instalar pacotes, mas funcionará como atualmente com o sinalizador -d  habilitado, o que significa que ajustará o atual dependências do módulo sem construir pacotes. O sinalizador -insecure  ou -i  a também foi descontinuado. 
Os autores do pacote agora podem retirar versões antigas
 A partir do Go 1.16, uma nova diretiva de retração estará disponível nos arquivos  go.mod . Isso permite que os autores dos pacotes marquem as versões mais antigas do pacote como inseguras ou quebradas ou se uma versão foi publicada acidentalmente. Veja como usá-lo: 
exemplo do módulo
ir 1,16 retrair v1.1.1//retrair versão única retrair [v1.1.1, v1.3.2]//intervalo fechado, então qualquer coisa entre v1.1.1 e v1.3.2
 O pacote  io/ioutil  agora está obsoleto 
 O pacote  ioutil  inteiro agora está obsoleto no Go 1.16 e suas funções foram movidas para outros pacotes. Para ser claro, o código existente que utiliza este pacote continuará a funcionar, mas você é incentivado a migrar para as novas definições nos pacotes  io  e  os . 
 A migração de código usando  ioutil  deve ser direta. Um método popular neste pacote é o método  ReadAll () , que geralmente é usado para ler todo o corpo de resposta de uma solicitação HTTP em uma fatia de bytes. Este método foi movido para o pacote  io : 
 resp, err:=http.Get (url)
se errar!=nulo { return err
} adiar resp.Body.Close () //maneira antiga: corpo, erro:=ioutil.ReadAll (resp.Body)
corpo, errar:=io.ReadAll (resp.Body)
se errar!=nulo { return err
}
 A lista completa dos novos locais dos métodos  io/ioutil  exportados é mostrada abaixo: 
- ioutil.Discard => io.Discard
- ioutil.NopCloser => io.NopCloser
- ioutil.ReadAll => io.ReadAll
-   ioutil.ReadDir =>  os.ReadDir  (retorna uma fatia de os.DirEntryem vez de uma fatia defs.FileInfo)
- ioutil.ReadFile => os.ReadFile
- ioutil.TempDir => os.MkdirTemp
- ioutil.TempFile => os.CreateTemp
- ioutil.WriteFile => os.WriteFile
 O pacote  io/fs  
 As melhorias na biblioteca padrão Go não foram deixadas de fora nesta versão com a adição dos pacotes  io/fs  e  testing/testfs . Esses novos pacotes tornam mais fácil abstrair um sistema de arquivos em testes, o que os torna mais facilmente reproduzíveis, independentemente do sistema operacional em que estão sendo executados. O acesso aos arquivos também será muito mais rápido e você não terá que limpar os arquivos temporários depois. 
Antes do Go 1.16, a tarefa de simular um sistema de arquivos frequentemente recaía sobre o popular afero pacote que fornece um tipo de interface que deve esteja satisfeito em implementar um sistema de arquivos real ou simulado. Ele também fornece algumas implementações comuns que fornecem essa interface, como afero. MemMapFs , que é um sistema de arquivos de memória útil para simulação em testes.
 Ao contrário da interface  Fs  do afero que define 13 métodos no momento da escrita, a interface  FS  fornecida pelo pacote  io/fs  é bastante simples: 
interface de
 tipo FS { Abrir (string de nome) (arquivo, erro)
}
 Tudo que você precisa fazer para implementar esta interface é um método  Open  que pode abrir um arquivo em um caminho e retornar um objeto que implementa a interface  fs.File  que é mostrado abaixo: 
 type File interface { Stat () (FileInfo, erro) Ler ([] byte) (int, erro) Fechar () erro
}
 Uma coisa que você notará na interface acima é a falta de métodos que permitem a modificação de arquivos. Isso porque o pacote  io/fs  fornece apenas uma interface somente leitura para sistemas de arquivos, ao contrário do Afero, que é mais completo nesse aspecto. O  motivo  para esta decisão é que a leitura é mais fácil para resumir em comparação com a escrita, que é mais envolvente. 
Tudo isso é para dizer que acho que a decisão de design de limitar esta proposta para operações somente leitura é uma boa. Na verdade, foi o insight principal (por @robpike) que desbloqueou anos de estagnação e nos permitiu fazer qualquer progresso na definição dessa interface.
Menções notáveis 
 A ferramenta vet agora fornece um aviso quando uma chamada inválida para  testing.T  ou  testing.B  de  Fatal ,  Os métodos Fatalf  ou  FailNow  são feitos de dentro de uma goroutine criada durante um teste ou benchmark. Isso ocorre porque esses métodos saem do goroutine em vez da função de teste ou benchmark: 
 pacote principal importar"teste" função TestFoo (t * testing.T) { go func () { se for verdade { t.Fatal ("Teste falhou")//sai do goroutine em vez de TestFoo } } ()
}
  
 As chamadas para os métodos acima podem ser substituídas por  t.Error ()  para sinalizar a falha do teste e uma instrução  return  para sair do goroutine: 
 pacote principal importar"teste" função TestFoo (t * testing.T) { go func () { se for verdade { t.Error ("Teste falhou.") Retorna } } ()
}
Houve também várias pequenas atualizações e correções para pacotes de biblioteca padrão. A lista completa de alterações pode ser encontrada nas notas de versão .
Conclusão
Se você quiser explorar a lista completa de correções de bugs e recursos incluídos nesta versão, encorajo você a verificar a lista de problemas encerrados em Go 1.16 milestone no GitHub.
Obrigado por ler e feliz programação!
A postagem O que há de novo no Go 1.16 apareceu primeiro em LogRocket Blog .
 
													 
													