golang系列的文章包含多篇文章,总篇如下,其中包含各篇文章的指引


之前没有接触过golang,但是最近接手的项目是用golang开发的,简单的修修改改还是可以的,毕竟语言都是相通的。但是项目完成后还是希望系统的学习一下,所以计划接下来会有一个系列的文章讲述go的学习过程。

按照往常的语言类教程,一般会直接教大家了解基础语法或者写个hello wrold之类的等等。但是我习惯先从结构上了解项目的结构和管理流程,然后再深入其中,所以我将项目管理放在了第一篇。本章将在docker容器中完成golang环境的搭建,并简述golang项目的结构和管理。在之前的文章中有讲述如何利用docker容器打造自己的开发环境,那本文就在容器中配置一套golang的开发环境,当然不使用docker而直接在本机开发环境中配置也是可以的。如果同学们不知道如何使用docker,可以先看看《Docker个人理解与初级使用》。

1、下载ubuntu的镜像后生成一个容器,并启动它,具体方式见《Docker个人理解与初级使用》。然后在容器中下载golang的安装包,进行安装。在golang官网上我们可以看到各个平台的各个版本的golang安装包或源码,这里我选择用wget下载Linux go1.13.5版本。如果没有安装wget,可以先安装:

apt-get install wget

安装完成后就可以下载go了,例如:

wget https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz

下载完成之后解压如下所示。为什么要解压到/usr/local/go目录呢,可以将该目录理解成windows的C盘下的一个目录,例如我们一般将微信、photoshop等文件放在C盘下,因为我们一般不会去修改C盘下的内容。因此,把go安装的/usr/local下,能够方便管理我们安装的各种软件,同时也与我们的工作目录隔离,避免工作时将程序的环境污染。另一方面,只要将/usr/local/go目录放在系统的环境变量中,那么在任何目录下都可以像执行shell命令一样执行go的命令。

tar -C /usr/local/go -zxvf go1.13.5.linux-amd64.tar.gz

重要信息:

由于golang在1.13版本及以上版本已经全面支持module机制,极大方便同学们配置环境并构建项目;基于新机制的文章如下所示:

如果同学们想了解基于verdor机制的旧版构建方法,则继续阅读本文;讲解module机制的文章由上述链接进行跳转即可。


将/usr/local/go目录添加到环境变量中:

vim /etc/profile
#在文件最后添加如下2行内容后保存退出
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
#最后更新/etc/profile即可
source /etc/profile
  • GOROOT变量记录的是golang的安装目录,即前文我们指定的解压目录;
  • GOROOT/bin下则记录的是go的原始可执行文件目录,即go build中的go;
  • /etc/profile文件存储所有用户的环境变量,所以我们在其中加入golang的安装目录,那么所有用户可以在任意目录下执行go的命令,例如查看go的版本等。
go version
go version go1.13.4 linux/amd64
#如果查询版本失败,可以尝试退出docker后再次开启docker查询

当然,这也意味着你可以写一段hello world的代码了,一个文件、几行代码即可搞定。但是这仅仅是停留在代码的级别,而我希望从项目的级别写一个hello world,毕竟我们要具有将一个项目从无到有的能力。下面主要讲解一下在golang语言下如何将hello world写成一个项目。

1、首先我们需要新建一个工作目录,或者准确的说是golang项目的工作目录,例如新建一个go_project的目录,这个目录中将存放今后所有的golang的项目。当然你可以新建很多个工作目录。

mkdir go_project

2、很多IDE都是通过新建一个项目作为第一步,那么我们如果要做一个hello world的项目,也需要新建一个项目,即在工作目录go_project下新建hello world的项目。从项目开发的角度来讲,工作目录下应该有bin、pkg和src目录。

  • bin目录主要存放所有golang项目编译后生成的可执行文件,例如hello_world、main、hahaha等
  • pkg目录主要存放各种库文件和中间状态文件,暂时可以忽略
  • src目录主要存放各个项目的源文件,例如hello_world、main、hahaha三个项目的原文件

那么我们的hello world项目该怎么组织呢?如下图所示:

hello_world 项目组织结构

如果按照上述的组织方式,bin目录下将存放main.go编译后生成的main可执行文件;由于main.go没有库文件生成,所以pkg中没有内容;src目录中thirdparty将存放第三方库,一般在项目开发过程中都会引用第三方库,所以如果使用这种方法组织代码,所有项目的第三方库就应该都放在thirdparty目录中;src目录中的hello_world就是我们的项目目录,当然还有other_project1和other_project2等其他项目;hello_world项目中仅包含main.go和Readme。

题外话:如果所有项目引用的第三方库都放在thirdparty下,那么如果需要将某个项目拷贝给同事,那么你需要从thirdparty中找出所有相关的第三方库发给同事,这是如此的繁琐。当然有解决办法,同学们可以先自己google一下,下一篇文章将给出解决方案。

main.go的内容是如此的简单,我就不详细解释了,大家可以在很多地方google到,值得提到的是golang的左花括号必须和方法声明在同一行,否则编译会报错,main.go的内容如下:

package main
import "fmt"
func main(){
        fmt.Println("hello world")
}

golang的编译指令为go build,然后进行编译:

go build main.go

之后在同级目录下就能看到main的可执行文件并且可执行输出hello world。然后我们期望用go install同时完成编译+安装步骤,这样应该会在go_project/bin下生成可执行文件main(前面说过,go_project/bin下的目录保存生成的可执行文件)

go install main.go

然而,事与愿违,go_project/bin目录下空空如也。为什么呢?原因在于我们并没有告诉编译器将编译后的可执行文件安装在go_project/bin下,那如何告诉编译器呢?golang提供了两个变量:GOPATH和GOBIN。

  • GOPATH保存的是我们的工作目录,即go_project目录;
  • GOBIN保存的就是可执行文件的安装目录,即go_project/bin目录。

只要告诉编译器:我在GOPATH下工作,你把可执行文件放到GOBIN下去吧,编译器就会按指令执行。所以我们需要将这两个变量也加入到环境变量中,则最终的配置为:

vim /etc/profile
#在文件最后再添加GOPATH和GOBIN的内容后保存退出
export GOROOT=/usr/local/go
export GOPATH=/home/go_program
export GOBIN=$GOPATH/bin/
export PATH=$PATH:$GOPATH/bin
export PATH=$PATH:$GOROOT/bin
#最后更新/etc/profile即可
source /etc/profile

此时,再次执行go install main.go指令则可以将可执行文件main放到go_project/bin目录下,同时由于GOBIN目录在系统环境中,那么在任意目录都可以执行main。值得注意的是,GOPATH千万不要设置成GOROOT相同的目录,否则万一你生成了一个名字为go的可执行文件,那么安装GOBIN目录下后实际上会覆盖golang本身的go程序,导致你的golang环境被破坏。

当然,到这里并没有结束。同学们还需要将这个环境保存到docker的新镜像,这样再从新镜像生成的容器自动包含golang的开发环境,再也不用重新配置了。具体的方式见《Docker个人理解与初级使用》。

至此,同学们就可以进行简单的golang的程序的学习和开发了,但是这样离项目管理还差一步:go getvender机制,这两个内容会再下一篇文章讲解,同时也会给出同事之间如何进行共享完整的项目代码的方法。