Chinese (Simplified) (中文(简体)) translation by Qiang Ji (you can also view the original English article)
Go在现代语言中是一种特别的语言。 它非常的固执己见。 比如,它只有一种真正的格式。 Go会告诉你如何分隔你的代码和在哪里摆放你的花括号。 但它不仅仅只有这些。
Go还会告诉你如何将你的函数和变量首字母大写,以使它们成为公共的或私有的函数或变量。 它将决定你代码的目录结构。 这可能会给那些从更自由的编程语言转到Go的开发者带来惊喜。
在这篇文章中,我将探讨一些Go的限制,讨论它们的优点,并为常见的状况建议一些选择。
Euler项目
当我开始学习Go时,我为第6个问题创建了一个解决方案,我就把它放在一个子目录中,就在那些用其他语言创建的,针对其他问题的解决方案的旁边。 参见Euler项目
问题是Go并不想让你到处随机地摆放Go文件。 我后来意识到(虽然这在非常简单的情况下比如你不导入其它包的时候是工作的)它是不正确的。
依赖
每个重要的程序都是由多个文件、模块、组件或类组成。 我就用“文件”作为一个通用的术语。 它们常常以库、包或程序集分组。 我就用“包”作为一种通用的术语。 你编写的代码依赖其它文件和包中的代码。
你需要告诉你的代码如何去找到这些包和文件以使用其功能。 每个语言都有它自己的术语:导入(import), 包含(include)和 需要(require). 我就用“导入(import)"作为一种通用的术语。
某些语言(或特定于语言的工具)还允许从远程软件包存储库安装依赖关系,并将它们安装到一个标准的本地位置,你可以从这些地方导入它们。
在大多数常见的编程语言中,你有很多的自由。 在C / C ++中,你可以告知编译器/链接器文件和静态库在哪里(使用命令行开关或环境变量,如INCLUDE_DIR)。 在Python中,你可以使用setup.py从PyPI或远程源代码控制库来安装软件包。 然后你可以根据sys.path包搜索路径导入。
Go的方式
Go,一如既往,更加的规范。 它可能冒犯了你的创造力,你不能想放在那里就放在那里,但最终这并没有那么重要,它能足够灵活地去适应各种情况。
Go要求你将代码放在工作区中。 工作区只是一个具有三个子目录的目录:src,pkg和bin。 它建议你将所有的项目保存在单个工作区下。 这样它们可以彼此依赖并共享通用的第三方包。
注意:我目前使用Windows和PowerShell来做许多的交互示例。 对于以下部分,我想使用tree
命令显示我的工作区的目录结构。 Windows有自己的tree.exe命令,但它非常有限(无层级)。 据说在这里有一个成熟的可使用在Windows下的tree命令。
但这网站打不开。 我最终创建了一个运行Ubuntu的Docker容器,将我的Go工作区架设在路径/docs/Go,并使用Linux tree命令显示它。 所以不要困惑,如果你看到一个Linux环境显示Windows目录和.exe后缀的文件。
这里是我目前的Go工作区。 bin目录包含不同的Go命令/工具,和delve调试器。 pkg
目录有一个带平台(Win 64)的子目录,该平台包含按代码库源(github.com,golang.com等)组织的包。 src
目录有个与其原始代码库或网站(github.com,golang.org等)类似的子目录。
root@67bd4824f9d5:/docs/Go# tree -n -L 3 |-- bin | |-- dlv.exe | |-- go-outline.exe | |-- go-symbols.exe | |-- gocode.exe | |-- godef.exe | |-- golint.exe | |-- gometalinter.exe | |-- gopkgs.exe | |-- gorename.exe | |-- goreturns.exe | `-- guru.exe |-- pkg | `-- windows_amd64 | |-- github.com | |-- golang.org | |-- gopkg.in | `-- sourcegraph.com `-- src |-- github.com | |-- alecthomas | |-- derekparker | |-- go-web-crawler | |-- golang | |-- google | |-- lukehoban | |-- multi-git | |-- newhook | |-- nsf | |-- rogpeppe | |-- tpng | `-- x |-- golang.org | `-- x |-- gopkg.in | `-- alecthomas `-- sourcegraph.com `-- sqs 27 directories, 11 files
让我们来看看我在src
下创建的一个源项目:go-web-crawler。 这里很简单:只是Go文件的简单列表,一个许可证和一个README文件。
root@67bd4824f9d5:/docs/Go# tree src/github.com/go-web-crawler/ -n src/github.com/go-web-crawler/ |-- LICENSE |-- README.md |-- channel_crawl.go |-- main.go `-- sync_map_crawl.go 0 directories, 5 files
GOROOT 和 GOPATH
两个环境变量控制你在GO领地的命运。 GOROOT
就是Go被安装的地方。
09:21:26 C:\Users\the_g\Documents\Go> ls Env:\GOROOT Name Value ---- ----- GOROOT C:\Go\ 09:21:35 C:\Users\the_g\Documents\Go> ls c:\go Directory: C:\go Mode LastWriteTime Length Name ---- ------------- ------ ---- d----- 8/16/2016 10:38 AM api d----- 8/16/2016 10:38 AM bin d----- 8/16/2016 10:38 AM blog d----- 8/16/2016 10:38 AM doc d----- 8/16/2016 10:38 AM lib d----- 8/16/2016 10:38 AM misc d----- 8/16/2016 10:38 AM pkg d----- 8/16/2016 10:38 AM src d----- 8/16/2016 10:38 AM test -a---- 8/16/2016 1:48 PM 29041 AUTHORS -a---- 8/16/2016 1:48 PM 1168 CONTRIBUT -a---- 8/16/2016 1:48 PM 40192 CONTRIBUT -a---- 8/16/2016 1:48 PM 1150 favicon.i -a---- 8/16/2016 1:48 PM 1479 LICENSE -a---- 8/16/2016 1:48 PM 1303 PATENTS -a---- 8/16/2016 1:48 PM 1638 README.md -a---- 8/16/2016 1:48 PM 26 robots.tx -a---- 8/16/2016 1:48 PM 5 VERSION
注意,Go根目录看起来像是一个具有src,bin和pkg目录的工作区的超集。
GOPATH
指向你的工作区。 这就是如何让Go找到你的代码。
09:21:53 C:\Users\the_g\Documents\Go> ls Env:\GOPATH Name Value ---- ----- GOPATH c:\Users\the_g\Documents\Go
还有一堆其它与Go相关的环境变量,在过去有许多需要你去设置(例如GOOS
和GOARCH
)。 现在,它们是可选的,你不应该弄乱它们,除非你真的需要(例如,当交叉编译时)。 要查看所有Go环境变量,请输入:go env
。
09:51:10 C:\Users\the_g> go env set GOARCH=amd64 set GOBIN= set GOEXE=.exe set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOOS=windows set GOPATH=c:\Users\the_g\Documents\Go set GORACE= set GOROOT=C:\Go set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64 set CC=gcc set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 set CXX=g++ set CGO_ENABLED=1
安装和导入
当你创建一个Go程序或一个库时,你可以安装它们。 程序会被安装在你工作区的bin
目录里,库会被安装在工作区的pkg
目录里。 在Windows操作系统中,我发现你的%GOPATH%/bin
不在%PATH%
目录中,所以Windows操作系统找不到我的可执行文件。 我把它加入Windows操作系统的PATH后所有的东西都工作了。 这是是如何在PowerShell中检查是否你的PATH包含你工作区的bin目录。
10:56:19 C:\Users\the_g> $env:path.split(";") | grep go C:\Go\bin c:\Users\the_g\Documents\Go\bin
让我们看一下它们在实际中的运用。
如果我进入go-web-crawler目录并且输入go install
,那么go-web-crawler.exe会在c:\Users\the_g\Documents\Go\bin
目录里被创建。
11:09:18 C:\Users\the_g> ls $env:GOPATH/bin Directory: C:\Users\the_g\Documents\Go\bin Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 8/15/2016 11:05 AM 15891456 dlv.exe -a---- 8/15/2016 10:08 AM 3972608 go-outline.exe -a---- 8/15/2016 10:10 AM 4502528 go-symbols.exe -a---- 9/18/2016 10:14 AM 1849856 go-web-crawler.exe -a---- 8/15/2016 10:08 AM 12097024 gocode.exe -a---- 8/15/2016 10:17 AM 6642688 godef.exe -a---- 8/15/2016 9:32 AM 6625792 golint.exe -a---- 8/15/2016 10:14 AM 6352896 gometalinter.exe -a---- 8/15/2016 10:10 AM 2738688 gopkgs.exe -a---- 8/15/2016 10:10 AM 6961152 gorename.exe -a---- 8/15/2016 10:09 AM 7291904 goreturns.exe -a---- 8/15/2016 10:11 AM 9722368 guru.exe
我现在能从任何地方运行我的Go网页爬虫。
11:10:32 C:\Users\the_g> go-web-crawler.exe found: http://golang.org/ "The Go Programming Language" found: http://golang.org/cmd/ "" not found: http://golang.org/cmd/ found: http://golang.org/pkg/ "Packages" found: http://golang.org/pkg/os/ "Package os" found: http://golang.org/pkg/fmt/ "Package fmt" found: http://golang.org/ "The Go Programming Language"
多重Go环境
到目前为止这一切都很好,但有时候生活不是那么简单。 你也许想有多个单独的工作区。 此外,你也许想安装多个Go(例如不同的版本)和多个工作区。 你可以通过动态地设置GOPATH
改变工作区和设置GOROOT
改变活跃的Go安装来实现,
有各种开发,包管理和虚拟环境的开源项目。 由于某些原因,大多数不支持Windows操作系统。 我不知道为什么这样的工具必须是平台特定的。 某天,我可以自己写一个跨平台的Go环境管理器。
结论
Go的发明是有关消除偶然的复杂性。 有时它非常的严格和规范。 但是,如果你进入了Go设计师的心态,你开始明白,避免,禁止或强制某些事情真的使一切更简单。