1. Go安装

1.1. 下载地址

Go官网下载地址:https://golang.org/dl/
Go官方镜像站:https://golang.google.cn/dl/

1.2. windows配置环境变量

1.2.1. PATH

image.png

1.2.2. GOPATH

GOPATH是一个环境变量,用来表明你写的go项目的存放路径(工作目录)。GOPATH路径最好只设置一个,所有的项目代码都放到GOPATH的src目录下。Go1.11版本之后,开启go mod模式之后就不再强制需要配置GOPATH了。
image.png
image.png

1.2.3. 添加GOPATH到PATH

image.png

1.3. Linux下配置环境变量

参考: https://www.yuque.com/duduniao/go/hjzb#1DfPg


2. Go开发环境

2.1. GOPATH

在v1.11版本之前,go工程代码需要放在 $GOPATH/src下,这种管理方式存在一个很大问题:第三方包和源码同放在一个目录下,而且还缺乏版本控制!因此在go1.11 之后的版本中,开发者基本不再使用gopath方式进行开发。

2.2. GOMOD

Gomod在v1.11版本推出,在v1.14中足够成熟,可以用于生产环境,Gomod可以让项目目录不再约束在$GOPATH/src下,此时不同的项目可以使用同一个第三方库的不同版本。在推出gomod之后,基本没必要再使用老的GOPATH模式进行开发。

2.2.1. 初始化git仓库

此处以gitee仓库为例,如果只是本地开发,可以跳过该步骤

  1. [root@duduniao gitee]# mkdir go-learn
  2. [root@duduniao gitee]# cd go-learn/
  3. [root@duduniao go-learn]# git init
  4. Initialized empty Git repository in /opt/projects/gitee/go-learn/.git/
  5. [root@duduniao go-learn]# git config user.name "渡渡鸟"
  6. [root@duduniao go-learn]# git config user.email "duduniao@qq.com"
  7. [root@duduniao go-learn]# touch README.md
  8. [root@duduniao go-learn]# git add README.md
  9. [root@duduniao go-learn]# git commit -m "first commit"
  10. [root@duduniao go-learn]# git remote add origin git@gitee.com:linux_duduniao/go-learn.git
  11. [root@duduniao go-learn]# git push -u origin master
  12. [root@duduniao go-learn]# git branch develop
  13. [root@duduniao go-learn]# git checkout develop
  14. Switched to branch 'develop'
  15. [root@duduniao go-learn]# git branch -a
  16. * develop
  17. master
  18. remotes/origin/master

2.2.2. 简单使用gomod

  • 初始化项目

    1. [root@duduniao go-learn]# go mod init gitee.com/linux_duduniao/go-learn # 创建gomod项目
  • 编写一个简单的go代码 ```go [root@duduniao go-learn]# vim main.go package main

import ( // 导入日志模块 logger “github.com/sirupsen/logrus” )

func main() { logger.Info(“test”) }

  1. - 生成gomod依赖

生成gomod依赖

[root@duduniao go-learn]# go mod tidy

go.mod 文件内容

[root@duduniao go-learn]# cat go.mod module gitee.com/linux_duduniao/go-learn

go 1.16

require github.com/sirupsen/logrus v1.8.1

go.sum 文件内容

[root@duduniao go-learn]# cat go.sum github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

  1. <a name="fhb3u"></a>
  2. ### 2.2.3. gomod深入学习
  3. 以下部分适合已经学习过一段时间golang开发同学学习!**本章节参考的是**[** anqiansong **](https://github.com/anqiansong/golang-notes/blob/main/go-module.md)**笔记和 [官方文档](https://golang.org/ref/mod) **!<br />gomodule 有两个关键文件:go.mod 和 go.sum,go.mod文件是学习gomod的关键
  4. <a name="ZcfPM"></a>
  5. #### 2.2.3.1. go.mod
  6. ```go
  7. module gitee.com/linux_duduniao/go-learn
  8. go 1.16
  9. require (
  10. gitee.com/linux_duduniao/apiserver v0.0.0
  11. github.com/Microsoft/go-winio v0.5.0 // indirect
  12. github.com/containerd/containerd v1.5.2 // indirect
  13. github.com/docker/docker v20.10.7+incompatible
  14. github.com/docker/go-connections v0.4.0 // indirect
  15. github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
  16. github.com/morikuni/aec v1.0.0 // indirect
  17. github.com/sirupsen/logrus v1.8.1
  18. golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
  19. golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
  20. golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 // indirect
  21. golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
  22. golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
  23. golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 // indirect
  24. google.golang.org/appengine v1.6.7 // indirect
  25. google.golang.org/genproto v0.0.0-20210708141623-e76da96a951f // indirect
  26. google.golang.org/grpc v1.39.0 // indirect
  27. gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
  28. k8s.io/api v0.21.2 // indirect
  29. k8s.io/apimachinery v0.21.2
  30. k8s.io/client-go v0.21.2
  31. k8s.io/klog/v2 v2.9.0 // indirect
  32. k8s.io/utils v0.0.0-20210709001253-0e1f9d693477 // indirect
  33. sigs.k8s.io/structured-merge-diff/v4 v4.1.2 // indirect
  34. )
  35. replace (
  36. gitee.com/linux_duduniao/apiserver => ./src/apiserver
  37. )
  38. excule (
  39. k8s.io/client-go v0.21.0
  40. )

以上的 go.mod 文件中,line 1 表示当前工程项目的模块名称; line 3 表示当前使用的 go mod init 时使用的go语言版本。require 代码块表示当前项目依赖的模块。

  • require 的版本号问题:

版本号格式为: v{major}.{minor}.{patch} ,一般而言,当 major 为0或者 patch 带有 pre, beta 时,表示版本不稳定。上述的 line 11、line 14 是伪版本号,会增加时间戳和修订标识符。
在gomod推荐的版本管理系统中,建议将 major 写在模块名称末尾,比如当前go-learn的Tag到v3.0.0时,module应当修改为 gitee.com/linux_duduniao/go-learn/v3 。如果没有修改 go.mod 或者不存在 go.mod ,被引用时,会打上 +incompatible 标志

  • indirect 含义

indirect 表示间接依赖,当项目A引用B,B引用C1和C2时:如果B没有启用go.mod,则C1,C2作为间接引用出现在A的go.mod文件中。当B启用了go.mod,但是C2不在其go.mod中时,C2作为间接引用出现在 A 的go.mod中。使用 go mod why -m pkg 可以显示为啥依赖该模块。

  • replace的使用

replace 用于替换require中的依赖,一般有以下三种情况会使用到:

  • 替换无法下载的包,如使用 github 中的包替换其它 URL 地址或版本的包
  • 替换本地自己的包,如 line 33
  • 替换fork的包,部分场景中需要对第三方包做修改且作为公共包对外时,会考虑fork一个到自己的仓库
    • exclude

用于排除指定版本的包,在实际的工程环境中很少使用!

2.2.3.2. go.sum

go.sum 用于记录各个依赖包版本的摘要,如果该依赖有 go.sum 还会记录 go.sum 的摘要。目的是用于防止依赖包被篡改,因为第三方模块的tag可能会被篡改,导致项目出现风险。go.sum 记录的依赖版本可能会比go.sum中使用到的多得多,这个并不会影响项目本地。在提交代码时,需要把 go.sum 和 go.mod 同时提交。当go.sum 合并分支发生冲突时,一般将两个go.sum文件内容合并后保存。

2.2.4. gomod常用指令

2.2.4.1. 环境变量

参考文档:goproxy.io

  1. 1. GO111MODULE
  2. GO111MODULE(111是指v1.11版本) 环境变量,该变量的值有三个:
  3. off: 禁用gomod模块,编译时从 GOPATHvendor目录下查找
  4. on: 启用gomod模块,编译忽略GOPATHvendor目录,只根据go.mod下载依赖
  5. auto(默认值): 当项目在$GOPATH/src之外,且根目录存在go.mod文件时,启用gomod模块
  6. 2. GOPROXY
  7. GOPROXY指定下载go模块的代理服务器地址,用于解决国内互联网环境访问国际互联网高延迟问题。
  8. https://goproxy.cn 是最常用,也是最稳定的国内代理,由七牛云支持的非盈利项目。
  9. 推荐在go1.13之后使用,配置GOPROXY=https://goproxy.cn,direct,其中direct是go1.13提供的特性,
  10. goproxy无法访问的适合会直接访问模块地址,一定程度上解决私有库问题
  11. go1.13之前使用 GOPROXY=https://goproxy.cn 指定私有库,不过在go1.13之前gomod也是非稳定功能
  12. 3. GOPRIVATE
  13. GOPRIVATE指定私有库地址,使得直接跳过GOPROXYGOSUMDB,可以用逗号分隔多个域名,也支持*的泛域名
  14. 如: GOPRIVATE=gitlab.ddn.com
  15. 4. GOSUMDB
  16. 该变量用于指定go.sum中摘要验证的数据库,golang为了第三方包的安全性,对第三方包的摘要做了数据库,地址为sum.golang.org
  17. 当设置了GOPROXY="https://proxy.golang.org"时,GOSUMDB指向"sum.golang.org",其它情况下默认关闭。
  18. 如果配置了GOPROXY为其它值,且需要开启摘要检验,可以指定为国内的gosum.io
  19. GOSUMDB=gosum.io+ce6e7565+AY5qEHUk/qmHc5btzW45JVoENfazw8LielDsaI+lEbq6
  20. GOSUMDBoff时,明确指定不启用摘要校验,go get 指定 -insecure 也可以跳过校验
  21. 5. GONOSUMDB
  22. 如果启用了GOSUMDB,且没有配置GOPRIVATE,那么需要指定GONOSUMDB,用于跳过不校验摘要的依赖,多个域名用分号分隔
  23. 如: GONOSUMDB=*.ddn.com

2.2.4.2. 相关指令

  1. 1. go mod init [module]
  2. 初始化gomod,会在项目目录下生成 go.mod 文件,如: go mod init github/duduniao/application.
  3. 如果是v2以上版本,golang建议在项目末尾加上大版本,如: github/duduniao/application/v3
  4. 2. go mod tidy [-e] [-v]
  5. 更新go.mod文件,移除不必要的模块,添加新的模块。
  6. -e: 在遇到错误的时候尽量继续
  7. -v: 显示移除的模块
  8. 3. go mod download [-json] [-x] [modules]
  9. 用于下载模块到gomod缓存目录下。
  10. -jons: json对象打印下载的模块信息
  11. -x: 默认donwload不会打印标准输出,只打印标准错误,使用-x打印执行过程到标准错误
  12. modules: 指定要下载的模块,可以是模块名@version,如果不指定modules,则下载所有go.mod中依赖
  13. 4. go mod edit [flags] [-fmt|-print|-json] [go.mod]
  14. 编辑go.mod文件,如添加、修改、删除go.mod内容。
  15. flags: flags 分为以下几种:
  16. -module: 用于修改模块路径
  17. -go=version: 修改golang版本
  18. -require=path@version: 添加require的模块
  19. -droprequire=path: 移除require的模块
  20. -replace=old[@v]=new[@v]: 替换模块,当new省略version,仅用于new为相对路径,不能为本项目目录之外的代码库
  21. -dropreplace=old[@v]: 移除replace中的模块
  22. -exclude=path@version, -dropexclude=path@version: 添加或移除模块
  23. -fmt: 格式化go.mod文件
  24. -print: 打印go.mod文件,以文本的形式
  25. -josn: 打印go.mod文件,以json格式
  26. 5. go mod verify
  27. 校验模块的摘要信息
  28. 6. go mod why [-m] [-vendor] packages...
  29. 打印为什么需要引入这个包
  30. 7. go mod vendor [-e] [-v]
  31. go.mod中用的模块从缓存目录迁移到项目根目录下的 vendor 目录下,这个目录可能会很大。
  32. 大部分情况下这个命令是没必要执行的,部分场景中由于CI过程中拉取代码存在问题才会考虑从vendor目录下获取依赖进行编译
  33. 当启用了 vendor 目录,编译和运行时指定 -mod=vendor 表示从vendor目录读取依赖而不是缓存中

2.3. 笔者Go项目开发环境

环境: win10 + wsl2(Ubuntu2004) + vscode + golang, 并不是最优解,仅供参考
当具备一定的golang基础后,一定要打造一个对你而言最佳的golang开发环境,这样对效率的提升是非常大的!

2.3.1. 安装wsl2和ubuntu2004

初学者不需要纠结工具,选择 goland 或者 vscode 在win10下开发可能更方便,当需要linux环境时,再考虑远程开发!
笔者是因为部分项目,需要Linux环境,并且笔者运维出身,对Linux命令行和shell非常熟悉,同时ubuntu2004可以更好的运行docker和CICD工具,可以在Linux场景下提升开发效率,所以才选择 wsl2 环境。
等待wsl2 GUIAPP 进入稳定版后,推荐使用 goland + wsl2 进行开发,这样效率会更高! 参考博客

  • 安装WSL2子系统
  • 安装Terminal终端

    terminal 配置文件:settings.json

    2.3.2. 安装golang

    ```

    golang各版本安装目录

    [root@duduniao ~]# ls -l /opt/release/golang/ total 24 drwxr-xr-x 4 root root 4096 Jan 30 11:38 gopath drwxr-xr-x 10 root root 4096 Feb 13 2020 v1.12.17 drwxr-xr-x 10 root root 4096 Aug 6 2020 v1.13.15 drwxr-xr-x 10 root root 4096 Jan 20 04:10 v1.14.14 drwxr-xr-x 10 root root 4096 Mar 12 01:13 v1.15.10 drwxr-xr-x 10 root root 4096 Jun 6 18:09 v1.16.2 [root@duduniao ~]# ls -l /opt/apps/go* -d lrwxrwxrwx 1 root root 27 Jun 6 18:09 /opt/apps/golang -> /opt/release/golang/v1.16.2 lrwxrwxrwx 1 root root 26 Jul 10 17:18 /opt/apps/gopath -> /opt/release/golang/gopath

环境变量配置

[root@duduniao ~]# cat .bash/exports export GOPATH=/opt/apps/gopath export BASE_PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin export PATH=$BASE_PATH:$GOPATH/bin

export GO111MODULE=on export GOPROXY=https://goproxy.cn,direct export GOPRIVATE=gitlab.local.com export CGO_ENABLED=0 export GOOS=linux export GOARCH=amd64

默认的go解释器

export GOROOT=/opt/apps/golang export PATH=$BASE_PATH:$GOROOT/bin export GOCACHE=/tmp/gocache

命令别名,在命令行可以快速切换不同版本的go环境

[root@duduniao ~]# cat .bash/aliases

本地访问国际互联网的代理服务器,用于下载golang依赖包

alias proxy=’export https_proxy=http://10.4.7.1:10080;export http_proxy=http://10.4.7.1:10080‘ alias unproxy=’unset https_proxy;unset http_proxy’

不同golang环境切换

alias go12=’export GOROOT=/opt/release/golang/v1.12.17; export PATH=$GOROOT/bin:$BASE_PATH’ alias go13=’export GOROOT=/opt/release/golang/v1.13.15; export PATH=$GOROOT/bin:$BASE_PATH’ alias go14=’export GOROOT=/opt/release/golang/v1.14.14; export PATH=$GOROOT/bin:$BASE_PATH’ alias go15=’export GOROOT=/opt/release/golang/v1.15.10; export PATH=$GOROOT/bin:$BASE_PATH’ alias go16=’export GOROOT=/opt/release/golang/v1.16.2; export PATH=$GOROOT/bin:$BASE_PATH’

应用以上配置

[root@duduniao ~]# cat .bashrc ……

sources

files=”/root/.bash/exports /root/.bash/aliases /root/.bash/commands /etc/bash_completion /usr/share/bash-completion/bash_completion” for i in $files do [ -e $i ] && source $i done ……

项目存放目录

[root@duduniao ~]# tree -L 2 /opt/projects/ /opt/projects/ ├── gitee │ ├── application │ └── image ├── gitlab │ └── k3s └── local └── ro_intaller

  1. <a name="U1Rmh"></a>
  2. ### 2.3.3. vscode配置
  3. 参考文档:
  4. - [https://zhuanlan.zhihu.com/p/320343679](https://zhuanlan.zhihu.com/p/320343679)
  5. - [https://code.visualstudio.com/docs](https://code.visualstudio.com/docs)
  6. ---
  7. <a name="bE249"></a>
  8. # 3. Go语言的基础语法
  9. ```go
  10. // main.go
  11. package main
  12. import "fmt"
  13. var testString string = "hello world!"
  14. func main() {
  15. fmt.Println(testString)
  16. }

3.1. 语言结构

  • 定义包名: package main ,在代码文件的非注释的第一行指定当前的代码文件属于哪个包。main表示一个可独立执行的程序
  • 导入包: import "fmt" ,使用import导入其它的包
  • 变量: var testString string = "hello world!" ,自定义变量
  • 函数: func main() {...} ,函数。其中main()函数为入口函数,可独立运行的项目会有一个main函数

    3.2. 基础语法

  • 注释:单行注释用双斜线 // ,多行注释用 /* ..... */ ,一般使用单行注释

  • 语句:建议一行一个语句,Go会自动对每一行后面添加 ;
  • 代码块:代码块用 { ... } 表示
  • 标识符:标识符一般采用小驼峰式命名,如 studentName ,首字母大写表示对当前Package之外可见

    3.3. 编译和运行程序

    golang 是静态语言,需要编译后才能执行: ``` [root@duduniao go-learn]# gofmt -w main.go # 格式化代码,用于统一代码风格 [root@duduniao go-learn]# go run main.go # 直接运行,其实是经历了编译,再运行 hello world!

[root@duduniao go-learn]# go build main.go # go build 表示编译,默认编译后的二进制文件存放到当前目录下 [root@duduniao go-learn]# ls README.md go.mod go.sum main main.go [root@duduniao go-learn]# ./main # 运行编译后的二进制文件 hello world!

[root@duduniao go-learn]# go build -o /tmp/hello_world main.go # 指定编译后二进制文件存放路径 [root@duduniao go-learn]# /tmp/hello_world hello world!

跨平台编译

CGO代码不支持跨平台编译,因此设置 CGO_ENABLED=0 ,设置平台 GOOS=linux|windows|darwin ,分别对应linux、windows、mac,架构GOARCH=amd64

如在windows编译成可以在linux执行的二进制文件

SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build ```

3.4. Go语言相关资料

Go语言官网: https://golang.org/
Go语言标准库: https://books.studygolang.com/The-Golang-Standard-Library-by-Example/;https://studygolang.com/pkgdoc
Go官方指南: https://tour.go-zh.org/welcome/1
李文周博客: https://www.liwenzhou.com/posts/Go/go_menu/