Portuguese (Português) translation by Erick Patrick (you can also view the original English article)
Go é uma linguagem especial entre as linguagens modernas. Tem opnião. Por exemplo, há uma verdadeira formatação. Go dirá como espaçar seu código e onde colocar as chaves. Mas vai muito além disso.
Go também dira como capitalizar suas funções e variáveis para torná-las públicas ou privadas. Ditará a estrutura de diretórios do seu código. Isso pode ser espantoso para desenvolvedores chegando ao Go vindo de linguagens masi liberais.
Hoje, exploraremos algumas das restrições da Go, discutiremos seus méritos e sugeriremos opções para situações comuns.
Projeto Euler
Ao começar a aprender Go, crei uma solução para o Problema #6 e pu-lo em uma subpasta, junto a outras soluções de outros problemas em outras linguagens. Veja o Projeto Euler.
O ponto é que o Go não quer que jogue arquivos Go ao léu por todos os lugares. Depois, percebi que, embor sirva para casos bem simples onde não importamos outros pacotes, não é apropriado.
Dependências
Todo programa não trivial é composto de múltiplos arquivos, módulos, componentes ou classes. Usaremos "arquivo" como termo genérico. Eles são agrupados em bibliotecas, pacotes ou montagens. Usaremos "pacote" genericamente. O códido que escrevemos depende de códigos de outros arquivos e pacotes.
Precisamos dizer ao nosso código como encontrá-los para usar suas funcionalidades. Cada linguagem tem seu próprio termo: import, include, require. Usaremos "impor" genericamente.
Algumas linguagens (ou ferramentas delas), também nos permitem instalar dependências de repositórios de pacotes remotos e instalá-los em um local padrão para importá-los.
Nas linguagens mais comuns, temos bastante liberdade. Em C/C++, dizemos ao compilador/vinculador onde os arquivos e bibliotecas estáticas estão (usando interruptores de linha de comando ou variáveis de ambiente como INCLUDE_DIR). No Python, podemos instalar pacotes pelo PyPi com setup.py ou com pip do PyPI e de repositórios de controle de código remotos. Então importamos baseado no caminoh de busca de sys.path.
O Caminho Go
Go, como sempre, é prescritiva. Talvez ofenda sua criatividade em dizer onde colocar as coisas, mas no fim das contas, não importa, e há flexibilidade suficiente para acomodar várias situações.
Go requer o código em um espaço de trabalho. Um diretório, com três sub diretórios: src, pkg e bin. É recomendado que mantenhamos todos nosso projetos em um único espaço de trabalho. Assim, podem depender um dos outros e compartilhar pacotes de terceiros.
Nota: Trabaho no Windows e uso o PowerShell em vários exemplos interativos. Para a sessão a seguir, quis mostrar a estrutura de diretórios do meu espaço de trabalho usando o comando tree
. Windows tem sua própria versão do comando, mas é limitado (sem níveis). Dizem que há um comando tree completo para Windows, aqui.
Mas o site estava inalcansável. Acabei executando um container do Docker rodando Ubuntu, montando um espaço de trabalho do Go em /docs/Go e usei o comando tree do Linux para mostrar. Então, não fique confuso se vir um ambiente Linux mostrans diretórios do Windows e arquivos .exe.
Eis nosso espaço de trabalho em Go atual. O diretório bin
contém vários comandos/ferramentas do Go e o depurador delve. O diretório pkg
tem um subdiretório da plataforma (Win 64) que contem pacotes organizados por suas origens (github.com, golang.com, etc.). O diretório src
tem subdiretórios similares para o repositório de origin ou site (github.com, golang.org, etc.).
1 |
root@67bd4824f9d5:/docs/Go# tree -n -L 3 |
2 |
|
3 |
|
4 |
|
5 |
|-- bin |
6 |
|
7 |
| |-- dlv.exe |
8 |
|
9 |
| |-- go-outline.exe |
10 |
|
11 |
| |-- go-symbols.exe |
12 |
|
13 |
| |-- gocode.exe |
14 |
|
15 |
| |-- godef.exe |
16 |
|
17 |
| |-- golint.exe |
18 |
|
19 |
| |-- gometalinter.exe |
20 |
|
21 |
| |-- gopkgs.exe |
22 |
|
23 |
| |-- gorename.exe |
24 |
|
25 |
| |-- goreturns.exe |
26 |
|
27 |
| `-- guru.exe |
28 |
|
29 |
|-- pkg |
30 |
|
31 |
| `-- windows_amd64 |
32 |
|
33 |
| |-- github.com |
34 |
|
35 |
| |-- golang.org |
36 |
|
37 |
| |-- gopkg.in |
38 |
|
39 |
| `-- sourcegraph.com |
40 |
|
41 |
`-- src |
42 |
|
43 |
|-- github.com |
44 |
|
45 |
| |-- alecthomas |
46 |
|
47 |
| |-- derekparker |
48 |
|
49 |
| |-- go-web-crawler |
50 |
|
51 |
| |-- golang |
52 |
|
53 |
|
54 |
|
55 |
| |-- lukehoban |
56 |
|
57 |
| |-- multi-git |
58 |
|
59 |
| |-- newhook |
60 |
|
61 |
| |-- nsf |
62 |
|
63 |
| |-- rogpeppe |
64 |
|
65 |
| |-- tpng |
66 |
|
67 |
| `-- x |
68 |
|
69 |
|-- golang.org |
70 |
|
71 |
| `-- x |
72 |
|
73 |
|-- gopkg.in |
74 |
|
75 |
| `-- alecthomas |
76 |
|
77 |
`-- sourcegraph.com |
78 |
|
79 |
`-- sqs |
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
27 directories, 11 files |
86 |
|
87 |
|
88 |
Vejamos o código de um dos projetos que criei dentro de src
: o go-web-crawler. É bem simples: apenas uma lista de arquivos Go, uma licença e um arquivo README.
1 |
root@67bd4824f9d5:/docs/Go# tree src/github.com/go-web-crawler/ -n
|
2 |
|
3 |
src/github.com/go-web-crawler/ |
4 |
|
5 |
|-- LICENSE |
6 |
|
7 |
|-- README.md |
8 |
|
9 |
|-- channel_crawl.go |
10 |
|
11 |
|-- main.go |
12 |
|
13 |
`-- sync_map_crawl.go |
14 |
|
15 |
|
16 |
|
17 |
0 directories, 5 files |
GOROOT e GOPATH
Duas variáveis de ambiente controlam nosso destino em Go. GOROOT
é onde Go está instalado:
1 |
09:21:26 C:\Users\the_g\Documents\Go> ls Env:\GOROOT |
2 |
|
3 |
|
4 |
|
5 |
Name Value |
6 |
|
7 |
---- ----- |
8 |
|
9 |
GOROOT C:\Go\ |
10 |
|
11 |
|
12 |
|
13 |
09:21:35 C:\Users\the_g\Documents\Go> ls c:\go |
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
Directory: C:\go |
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
Mode LastWriteTime Length Name |
26 |
|
27 |
---- ------------- ------ ---- |
28 |
|
29 |
d----- 8/16/2016 10:38 AM api |
30 |
|
31 |
d----- 8/16/2016 10:38 AM bin |
32 |
|
33 |
d----- 8/16/2016 10:38 AM blog |
34 |
|
35 |
d----- 8/16/2016 10:38 AM doc |
36 |
|
37 |
d----- 8/16/2016 10:38 AM lib |
38 |
|
39 |
d----- 8/16/2016 10:38 AM misc |
40 |
|
41 |
d----- 8/16/2016 10:38 AM pkg |
42 |
|
43 |
d----- 8/16/2016 10:38 AM src |
44 |
|
45 |
d----- 8/16/2016 10:38 AM test |
46 |
|
47 |
-a---- 8/16/2016 1:48 PM 29041 AUTHORS |
48 |
|
49 |
-a---- 8/16/2016 1:48 PM 1168 CONTRIBUT |
50 |
|
51 |
-a---- 8/16/2016 1:48 PM 40192 CONTRIBUT |
52 |
|
53 |
-a---- 8/16/2016 1:48 PM 1150 favicon.i |
54 |
|
55 |
-a---- 8/16/2016 1:48 PM 1479 LICENSE |
56 |
|
57 |
-a---- 8/16/2016 1:48 PM 1303 PATENTS |
58 |
|
59 |
-a---- 8/16/2016 1:48 PM 1638 README.md |
60 |
|
61 |
-a---- 8/16/2016 1:48 PM 26 robots.tx |
62 |
|
63 |
-a---- 8/16/2016 1:48 PM 5 VERSION |
64 |
|
Note que a raiz do diretório de Go parece uma espécie de espaço de trabalho, com seus diretórios src, bin e pkg.
GOPATH
aponta para seu espaço de trabalho. É como Go acha seu código.
1 |
09:21:53 C:\Users\the_g\Documents\Go> ls Env:\GOPATH |
2 |
|
3 |
|
4 |
|
5 |
Name Value |
6 |
|
7 |
---- ----- |
8 |
|
9 |
GOPATH c:\Users\the_g\Documents\Go |
10 |
Existem várias outras variáveis de ambiente relacionadas a GO, muitas eram obrigatórias configurarmos (GOOS
e GOARCH
, por exemplo). Agora, ela são opcionais e não deveríamos mexer nelas a menos que precisemos (por exemplo: multi-compilação). Para ver todas as variáveis de ambiente do Go, digite: go env
.
1 |
09:51:10 C:\Users\the_g> go env |
2 |
|
3 |
set GOARCH=amd64 |
4 |
|
5 |
set GOBIN= |
6 |
|
7 |
set GOEXE=.exe |
8 |
|
9 |
set GOHOSTARCH=amd64 |
10 |
|
11 |
set GOHOSTOS=windows |
12 |
|
13 |
set GOOS=windows |
14 |
|
15 |
set GOPATH=c:\Users\the_g\Documents\Go |
16 |
|
17 |
set GORACE= |
18 |
|
19 |
set GOROOT=C:\Go |
20 |
|
21 |
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64 |
22 |
|
23 |
set CC=gcc |
24 |
|
25 |
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 |
26 |
|
27 |
set CXX=g++ |
28 |
|
29 |
set CGO_ENABLED=1 |
Instalações e Importações
Ao criarmos um programa ou biblioteca em Go, podemos instalá-la. Programas vão para bin
e bibliotecas para pkg
do espaço de trabalho. No Windows, descobrimos que %GOPATH%/bin
não está no diretório %PATH%
, logo o Windows não acharia o executável. Adicionei ao PATH do Windows e tudo funcionou. Eis como verificar, no PowerShel, se o PATH contem o diretório bin do espaço de trabalho:
1 |
10:56:19 C:\Users\the_g> $env:path.split(";") | grep go |
2 |
|
3 |
|
4 |
|
5 |
C:\Go\bin |
6 |
|
7 |
c:\Users\the_g\Documents\Go\bin |
8 |
|
Vejamos tudo em ação.
Se formos ao diretório go-web-crawler e digitarmos go install
, o arquivo go-web-crawler.exe será criado em c:\User\the_g\Documents\Go\bin
:
1 |
11:09:18 C:\Users\the_g> ls $env:GOPATH/bin |
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
Directory: C:\Users\the_g\Documents\Go\bin |
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
Mode LastWriteTime Length Name |
14 |
|
15 |
---- ------------- ------ ---- |
16 |
|
17 |
-a---- 8/15/2016 11:05 AM 15891456 dlv.exe |
18 |
|
19 |
-a---- 8/15/2016 10:08 AM 3972608 go-outline.exe |
20 |
|
21 |
-a---- 8/15/2016 10:10 AM 4502528 go-symbols.exe |
22 |
|
23 |
-a---- 9/18/2016 10:14 AM 1849856 go-web-crawler.exe |
24 |
|
25 |
-a---- 8/15/2016 10:08 AM 12097024 gocode.exe |
26 |
|
27 |
-a---- 8/15/2016 10:17 AM 6642688 godef.exe |
28 |
|
29 |
-a---- 8/15/2016 9:32 AM 6625792 golint.exe |
30 |
|
31 |
-a---- 8/15/2016 10:14 AM 6352896 gometalinter.exe |
32 |
|
33 |
-a---- 8/15/2016 10:10 AM 2738688 gopkgs.exe |
34 |
|
35 |
-a---- 8/15/2016 10:10 AM 6961152 gorename.exe |
36 |
|
37 |
-a---- 8/15/2016 10:09 AM 7291904 goreturns.exe |
38 |
|
39 |
-a---- 8/15/2016 10:11 AM 9722368 guru.exe |
40 |
|
Agora, podemos user o vasculhador web de qualquer lugar.
1 |
11:10:32 C:\Users\the_g> go-web-crawler.exe |
2 |
|
3 |
|
4 |
|
5 |
found: http://golang.org/ "The Go Programming Language" |
6 |
|
7 |
found: http://golang.org/cmd/ "" |
8 |
|
9 |
not found: http://golang.org/cmd/ |
10 |
|
11 |
found: http://golang.org/pkg/ "Packages" |
12 |
|
13 |
found: http://golang.org/pkg/os/ "Package os" |
14 |
|
15 |
found: http://golang.org/pkg/fmt/ "Package fmt" |
16 |
|
17 |
found: http://golang.org/ "The Go Programming Language" |
Múltiplos Ambientes Go
Está tudo bem, mas a vida, às vezes, não é tão simples. Talvez queiramos ter múltiplos espaços de trabalho separados. E mais, talvez queiramos múltiplas versões do Go e múltiplos espaços de trabalho para cada uma. Podemos obter isso ao configurar GOPATH
, dinamicamente, para alterar o espaço de trabalhho, e configurar GOROOT
para alterar a instalação Go.
Existem vários projetos de código aberto para fornecimento, administração de pacores e ambientes virtuais. Por algum motivo, a maioria não suporta o Windows. Não sei porque plataformas tem de ser específicas para plataformas. Talvez crie um administrador de ambiente multiplataforma conta própria.
Conclusão
Go faz o máximo para elimitar a complexidade acidental. Algumas vezes, parece muito restrito e prescritivo. Mas se entrar na mentalidade dos projetista da Go, começará a entender que evitar, proibir ou mandar certas coisas realmente torna tudo mais simples.