Saiba mais sobre os pacotes

Concluído

Os pacotes em Go são como bibliotecas ou módulos em outras linguagens de programação. Você pode empacotar seu código e reutilizá-lo em outro lugar. O código-fonte de um pacote pode ser distribuído em mais de um .go arquivo. Até agora, temos escrito o main pacote e feito algumas referências a outros pacotes nativos.

Nesta seção, você aprenderá o que é um pacote. Você também aprenderá como criar um e como consumir pacotes externos.

Embalagem principal

Como você deve ter notado, até mesmo o programa mais simples do Go tem que fazer parte de um pacote. Normalmente, o pacote padrão é o main pacote, aquele que temos usado até agora. Se um programa fizer parte do main pacote, Go gerará um arquivo binário. Quando esse arquivo é executado, ele chama a main() função.

Em outras palavras, quando você usa o main pacote, seu programa produzirá um executável autônomo. Mas quando um programa faz parte de um pacote diferente do main, Go não gera um arquivo binário. Ele gera um arquivo de pacote (um arquivo que tem a .a extensão).

Em Go, os nomes dos pacotes seguem uma convenção. Um pacote usa a última parte de seu caminho de importação como seu nome. Por exemplo, a biblioteca padrão Go contém um pacote chamado math/cmplx, que fornece código útil para trabalhar com números complexos. O caminho de importação deste pacote é math/cmplx, e você o importa assim:

import "math/cmplx"

Para se referir a objetos no pacote, use o nome do pacote, cmplx, da seguinte forma:

cmplx.Inf()

Vamos criar um pacote.

Criar um pacote

Crie um novo diretório no $GOPATH/src diretório chamado calculator. Crie um ficheiro denominado sum.go. O diretório de árvore deve ser semelhante a este diretório:

src/
  calculator/
    sum.go

Inicialize o sum.go arquivo com o nome do pacote:

package calculator

Agora você pode começar a escrever as funções e variáveis para o pacote. Ao contrário de outras linguagens de programação, Go não fornece as public palavras-chave ou private para indicar se uma variável ou função pode ser chamada de fora ou dentro do pacote. Mas Go segue duas regras simples:

  • Se você quiser que algo seja privado, comece seu nome com uma letra minúscula.
  • Se você quiser que algo seja público, comece seu nome com uma letra maiúscula.

Então, vamos adicionar o seguinte código ao pacote de calculadora que estamos criando:

package calculator

var logMessage = "[LOG]"

// Version of the calculator
var Version = "1.0"

func internalSum(number int) int {
    return number - 1
}

// Sum two integer numbers
func Sum(number1, number2 int) int {
    return number1 + number2
}

Vejamos algumas coisas nesse código:

  • A logMessage variável só pode ser chamada de dentro do pacote.
  • A Version variável pode ser alcançada de qualquer lugar. Recomendamos que você inclua um comentário para descrever a finalidade dessa variável. (Esta descrição é útil para qualquer pessoa que use o pacote.)
  • A internalSum função só pode ser chamada de dentro do pacote.
  • A Sum função pode ser acessada de qualquer lugar. Recomendamos que você inclua um comentário para descrever a finalidade da função.

Para confirmar que tudo está funcionando, você pode executar o go build calculator comando no diretório. Se você fizer isso, observe que nenhum binário executável é gerado.

Criar um módulo

Você colocou a funcionalidade da calculadora dentro de um pacote. Agora é hora de colocar esse pacote em um módulo. Os módulos Go normalmente contêm pacotes que oferecem funcionalidades relacionadas. O módulo de um pacote também especifica o contexto que o Go precisa para executar o código que você agrupou. Essas informações contextuais incluem a versão Go para a qual seu código foi escrito.

Além disso, os módulos ajudam outros desenvolvedores a fazer referência a versões específicas do seu código e facilitam o trabalho com dependências. Outro benefício é que o código-fonte do nosso programa não precisa existir $GOPATH/src estritamente no diretório. Liberar essa restrição torna mais conveniente trabalhar com diferentes versões de pacotes em outros projetos ao mesmo tempo.

Então, para criar um módulo para o calculator pacote, execute este comando no diretório raiz ($GOPATH/src/calculator):

go mod init github.com/myuser/calculator

Depois de executar este comando, github.com/myuser/calculator torna-se o nome do módulo. Você usará esse nome para fazer referência a ele em outros programas. O comando também cria um novo arquivo chamado go.mod. Finalmente, o diretório de árvore agora se parece com este diretório:

src/
  calculator/
    go.mod
    sum.go

O conteúdo do go.mod arquivo deve se parecer com o código a seguir. (A versão Go pode ser diferente.)

module github.com/myuser/calculator

go 1.14

Para fazer referência ao seu calculator pacote em outros programas, você precisa importá-lo usando o nome do módulo. Neste caso, o nome é github.com/myuser/calculator. Agora vamos ver um exemplo de como usar este pacote.

Nota

Historicamente, gerenciar dependências no Go não tem sido fácil. O sistema de gestão da dependência ainda está em curso. Se você quiser saber mais sobre módulos, veja esta série de posts publicados no blog Go.

Fazer referência a um pacote local (um módulo)

Agora vamos usar o pacote. Continuaremos com o aplicativo de exemplo que estamos usando. Desta vez, em vez de ter a sum main função no pacote, vamos usar a que criamos anteriormente no calculator pacote.

A estrutura do arquivo de árvore agora deve ter esta aparência:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    main.go

Usaremos este código para o $GOPATH/src/helloworld/main.go arquivo:

package main

import (
  "fmt"
  "github.com/myuser/calculator"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
}

Observe que a instrução import usa o nome do pacote que você criou: calculator. Para chamar a Sum função desse pacote, você precisa incluir o nome do pacote, como em calculator.Sum. Finalmente, agora você também tem acesso à Version variável. Você chama assim: calculator.Version.

Se você tentar executar o programa agora, ele não funcionará. Você precisa dizer ao Go que está usando módulos para fazer referência a outros pacotes. Para fazer isso, execute este comando no $GOPATH/src/helloworld diretório:

go mod init helloworld

No comando anterior, helloworld é o nome do projeto. Este comando cria um novo go.mod arquivo, então agora o diretório de árvore tem esta aparência:

src/
  calculator/
    go.mod
    sum.go
  helloworld/
    go.mod
    main.go

Quando você abre o go.mod arquivo, você deve ver algo como o código a seguir. (A versão Go pode ser diferente.)

module helloworld

go 1.14

Como você está fazendo referência a uma cópia local do módulo, precisa informar a Go de que não deseja usar um local remoto. Então você precisa modificar manualmente o go.mod arquivo para incluir a referência, assim:

module helloworld

go 1.14

require github.com/myuser/calculator v0.0.0

replace github.com/myuser/calculator => ../calculator

A replace palavra-chave especifica para usar um diretório local em vez de um local remoto para o módulo. Neste caso, porque os helloworld e calculator programas estão em $GOPATH/src, a localização é simplesmente ../calculator. Se a origem do módulo estiver em um local diferente, você definirá o caminho local aqui.

Execute o programa usando este comando:

go run main.go

A saída deve ser a seguinte:

8
Version:  1.0

Desafio 1

O que acontece se você tentar chamar a logMessage variável ou a internalSum função do calculator pacote no aplicativo principal? Será que corre? Experimente!

Solução para desafios:

package main

import (
 "fmt"
 "github.com/myuser/calculator"
)

func main() {
    total := calculator.internalSum(5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.logMessage)
}

Publicar um pacote

Publicar um pacote Go é bastante fácil. Você só precisa disponibilizar o código-fonte do pacote publicamente. A maioria dos desenvolvedores usa o GitHub para disponibilizar pacotes ao público, e é por isso que às vezes você encontrará referências em github.com instruções de importação.

Por exemplo, se você quiser publicar seu calculator pacote em sua conta do GitHub, precisará criar um repositório chamado calculator. O URL deve ser semelhante a este:

https://github.com/myuser/calculator

Você fará a versão de seus pacotes marcando seu repositório, desta forma:

git tag v0.1.0
git push origin v0.1.0

Os desenvolvedores que desejam usar seu pacote (incluindo você) o referenciariam assim:

import "github.com/myuser/calculator"

Vamos falar com mais detalhes sobre como fazer referência a pacotes de terceiros.

Pacotes externos (de terceiros) de referência

Às vezes, seus programas precisam fazer referência a pacotes escritos por outros desenvolvedores. Normalmente, esses pacotes estão disponíveis no GitHub. As instruções a seguir para fazer referência a pacotes de terceiros funcionam se você estiver desenvolvendo um pacote (um pacote diferente de main) ou um programa autônomo (o main pacote).

Vamos adicionar uma referência ao rsc.io/quote pacote:

package main

import (
    "fmt"
    "github.com/myuser/calculator"
    "rsc.io/quote"
)

func main() {
    total := calculator.Sum(3, 5)
    fmt.Println(total)
    fmt.Println("Version: ", calculator.Version)
    fmt.Println(quote.Hello())
}

Se você estiver usando o Visual Studio Code, o go.mod arquivo será atualizado quando você salvar o arquivo. Agora tem a seguinte aparência:

module helloworld

go 1.14

require (
    github.com/myuser/calculator v0.0.0
    rsc.io/quote v1.5.2
)

replace github.com/myuser/calculator => ../calculator

Observe como rsc.io/quote faz referência a uma versão específica do pacote. Quando precisar atualizar as dependências do programa, você precisará alterar a versão aqui.

Execute o programa novamente usando este comando:

go run main.go

A saída deverá ter o seguinte aspeto:

8
Version:  1.0
Hello, world.

Todas as referências futuras a pacotes de terceiros precisarão estar no go.mod arquivo. Quando você executa ou compila o aplicativo, o Go baixará todas as suas dependências.