这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
主要是简单记录一下Go语言的环境搭建以及第一天学到的一些东西。
Go语言特点 语法简单 性能高 完善的工具链 快速编译 跨平台 垃圾回收
Go语言环境配置
1.安装Go
访问 go.dev/ ,点击 Download 下载对应平台安装包如图,安装即可。
直接安装next,非常快(此安装方式自动配置环境变量)
运行go version 可运行表示安装和配置完成。
如果不行那你可能需要检查一下环境变量:GOROOT 和 GOPATH
2.开发环境选择
可以选择安装 VS Code , 或者 Goland ,对于 VS Code,需要安装 Go 插件 。
我使用的是IntelliJ IDEA😉也要下载 Go插件。
这时你就可以愉快的new 一个项目了。
Go的开始
例子: 文件名:helloworld.go
package main
import "fmt"
func main() {
fmt.Println("Hello, 世界")
}
$ go run helloworld.go 编译一个或多个以.go结尾的源文件,链接库文件,并运行最终生成的可执行文件。
没有意外,这个命令会输出:
Hello, 世界
$ go build helloworld.go 这个命令生成一个名为helloworld的可执行的二进制文件
可执行的二进制文件(译注:Windows系统下生成的可执行文件是helloworld.exe,增加了.exe后缀名),之后你可以随时运行它(译注:在Windows系统下在命令行直接输入helloworld.exe命令运行),不需任何处理(译注:因为静态编译,所以不用担心在系统库更新的时候冲突,幸福感满满)。
$ ./helloworld
Hello, 世界
一些命令
go env用于打印Go语言的环境信息。
go run命令可以编译并运行命令源码文件。
go get可以根据要求和实际情况从互联网上下载或更新指定的代码包及其依赖包,并对它们进行编译和安装。
go build命令用于编译我们指定的源码文件或代码包以及它们的依赖包。
go install用于编译并安装指定的代码包及它们的依赖包。
go clean命令会删除掉执行其它命令时产生的一些文件和目录。
go doc命令可以打印附于Go语言程序实体上的文档。我们可以通过把程序实体的标识符作为该命令的参数来达到查看其文档的目的。
go test命令用于对Go语言编写的程序进行测试。
go list命令的作用是列出指定的代码包的信息。
go fix会把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。
go vet是一个用于检查Go语言源码中静态错误的简单工具。
go tool pprof命令来交互式的访问概要文件的内容。
Init函数和main函数
1.1. init函数
go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性。
有下面的特征:
1 init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等
2 每个包可以拥有多个init函数
3 包的每个源文件也可以拥有多个init函数
4 同一个包中多个init函数的执行顺序go语言没有明确的定义(说明)
5 不同包的init函数按照包导入的依赖关系决定该初始化函数的执行顺序
6 init函数不能被其他函数调用,而是在main函数执行之前,自动被调用
1.2. main函数
Go语言程序的默认入口函数(主函数):func main()
函数体用{}一对括号包裹。
func main(){
//函数体
}
1.3. init函数和main函数的异同
相同点:
两个函数在定义时不能有任何的参数和返回值,且Go程序自动调用。
不同点:
init可以应用于任意包中,且可以重复定义多个。
main函数只能用于main包中,且只能定义一个。
两个函数的执行顺序:
对同一个go文件的init()调用顺序是从上到下的。
对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的init()函数。
对于不同的package,如果不相互依赖的话,按照main包中"先import的后调用"的顺序调用其包中的init(),如果package存在依赖,则先调用最早被依赖的package中的init(),最后调用main函数。
如果init函数中使用了println()或者print()你会发现在执行过程中这两个不会按照你想象中的顺序执行。这两个函数官方只推荐在测试环境中使用,对于正式环境不要使用。
Go的(包管理)
我也刚认识。就好像maven与之java一样。
包管理的历史
- 在 1.5 版本之前,所有的依赖包都是存放在 GOPATH 下,没有版本控制。这个类似 Google 使用单一仓库来管理代码的方式。这种方式的最大的弊端就是无法实现包的多版本控制,比如项目 A 和项目 B 依赖于不同版本的 package,如果 package 没有做到完全的向前兼容,往往会导致一些问题。
- 1.5 版本推出了 vendor 机制。所谓 vendor 机制,就是每个项目的根目录下可以有一个 vendor 目录,里面存放了该项目的依赖的 package。
go build的时候会先去 vendor 目录查找依赖,如果没有找到会再去 GOPATH 目录下查找。 - 1.9 版本推出了实验性质的包管理工具 dep,这里把 dep 归结为 Golang 官方的包管理方式可能有一些不太准确。关于 dep 的争议颇多,比如为什么官方后来没有直接使用 dep 而是弄了一个新的 modules,具体细节这里不太方便展开。
- 1.11 版本推出 modules 机制,简称 mod。modules 的原型其实是 vgo,关于 vgo,可以自行搜索。
除此之外,社区也一直在有几个活跃的包管理工具,使用广泛且具有代表性的主要有下面几个:
- godep
- glide
- govendor
1.GOPATH
1、GOPATH的概念 可以通过go env命令查看Go的环境变量。
GOPATH 是 Go 语言中使用的一个环境变量,它使用绝对路径提供项目的工作目录( 也称为工作区) 。
工作目录是一个工程开发的相对参考目录,好比当你要在公司编写一套服务器代码,你的工位所包含的桌面、计算机及椅子就是你的工作区。
工作区的概念与工作目录的概念也是类似的。如果不使用工作目录的概念,在多人开发时,每个人有一套自己的目录结构,读取配置文件的位置不统一,
输出的二进制运行文件也不统一,这样会导致开发的标准不统一,影响开发效率。
GOPATH 适合处理大量 Go语言源码、多个包组合而成的复杂工程。
从 Go 1.8 版本开始,Go 开发包在安装完成后,将 GOPATH 赋予了一个默认的目录,参见下表
2、GOPATH的使用
GOPATH目录一般为:
$HOME/go
--bin # 存放编译后的可执行文件
--pkg # 依赖包编译后的*.a文件
--src # 存放源码文件,以代码包为组织形式
如下是一个完整的Go项目的开发目录:
my-go // my-go为GOPATH目录
-- bin -- myApp1 // 编译生成
-- myApp2 // 编译生成
-- myApp3 // 编译生成
-- pkg 依赖包编译后的*.a文件//
-- src -- MyApp1 // 项目1
-- models
-- controllers
-- others
-- main.go
-- MyApp2 // 项目2
-- models
-- controllers
-- others
-- main.go
设置GOPATH后,工程中使用 import的根目录是GOPATH中的src目录
GOPATH为/Users/lxxxxxk/GolandProjects,工程为/Users/lxxxxxk/Desktop/my-go/src/MyApp1
那么MyApp1中使用import导入本地包的时候,这样写:
import "MyApp1/models" // models为包名
也就是说,GOPATH下必须要有src目录,不然import导包的时候会找不到
import导包规则:
1、先去GOROOT/src/路径下找 /usr/local/go/src/MyApp1 (系统环境变量 $GOROOT,即使用go env命令显示的GOROOT)
2、如果1没有,就去Project GOPATH/src/路径下找 /Users/lxxxxxk/Desktop/my-go/src/MyApp1
3、如果2还没找到,就去Global GOPATH路径下找 /Users/lxxxxxk/GolandProjects(系统环境变量 $GOPATH,即使用go env命令显示的GOPATH)
3、idea设置GOPATH
图中的 Global GOPATH 代表全局 GOPATH,一般来源于系统环境变量中的 GOPATH;
Project GOPATH 代表项目所使用的 GOPATH,该设置会被保存在工作目录的 .idea目录下,不会被设置到环境变量的 GOPATH 中,但会在编译时使用到这个目录。
建议在开发时填写项目 GOPATH,每一个项目尽量只设置一个 GOPATH,不使用多个 GOPATH 和全局的 GOPATH。 否则可能会出现如下麻烦:
将某项目代码保存在 /home/davy/projectA 目录下,将该目录设置为 GOPATH。
随着开发进行,需要再次获取一份工程项目的源码,此时源码保存在 /home/davy/projectB 目录下,
如果此时需要编译 projectB 目录的项目,但开发者忘记设置 GOPATH 而直接使用命令行编译,
则当前的 GOPATH 指向的是 /home/davy/projectA 目录,而不是开发者编译时期望的 projectB 目录。
编译完成后,开发者就会将错误的工程版本发布到外网。
2.从Go 1.13开始,模块管理模式将是Go语言开发的默认模式。可以不使用GOPATH
使用GOPATH做包管理可能有一些问题:
- 在不使用额外的工具的情况下,Go的依赖包需要手工下载,
- 第三方包没有版本的概念,如果第三方包的作者做了不兼容升级,会让开发者很难受
- 协作开发时,需要统一各个开发成员本地
$GOPATH/src下的依赖包 - 引用的包引用了已经转移的包,而作者没改的话,需要自己修改引用。
- 第三方包和自己的包的源码都在src下,很混乱。对于混合技术栈的项目来说,目录的存放会有一些问题
新的包管理模式解决了以上问题
- 自动下载依赖包
- 项目不必放在GOPATH/src内了
- 项目内会生成一个go.mod文件,列出包依赖
- 所以来的第三方包会准确的指定版本号
- 对于已经转移的包,可以用replace 申明替换,不需要改代码
依赖的包将被下载到$GOPATH/pkg/mod路径下。
$ go mod init [项目名]
然后会生成一个 go.mod文件
go.mod:
参考:
Go中的GOPATH是什么 www.cnblogs.com/ailiailan/p…
Go包管理详解 zhuanlan.zhihu.com/p/92992277
拜拜了,GOPATH君 zhuanlan.zhihu.com/p/60703832