为什么要学 Go
- 性能优越感;Go 极其地快,其性能与 Java 或 C++相似。在使用中,Go 一般比 Python 要快 30 倍;
- 序列化/去序列化、排序和聚合中表现优异;
- 开发者效率较高;多种赋值、数据结构、指针、格式化以及内置的 HTTP 库等能使给开发者提供快速着手开发;
- 天然并发,Go 的并发性方法非常容易上手;
- 编译速度快;
- 增强团队语言聚合力;Go 非常简单,且易于学习。它只提供了基本功能而没有多余。Go 引入的新概念是 defer 声明,以及内置的 goroutines 和通道的并发性管理。
- Go 具备稳定的生态系统;Go 有着强大的工具支持。
- GOFMT,强制代码格式;Gofmt 用一种官方的形式规格代码,避免了不必要的讨论;
- Go 语言对 protocol buffers 和 gRPC 有一流的支持等;
国外如 Google、AWS、Cloudflare、CoreOS 等,国内如腾讯、知乎、哔哩哔哩、七牛、阿里等大厂都已经开始大规模使用 Golang 开发其云计算相关产品。 跟着世界级巨人的脚步应该不至于走错方向,而且 Golang 的设计哲学足以让人折服。
云风博客中曾说过这样一句话:
我发现我花了四年时间锤炼自己用 C 语言构建系统的能力,试图找到一个规范,可以更好的编写软件。结果发现只是对 Go 的模仿。缺乏语言层面的支持,只能是一个拙劣的模仿。
环境搭建
下载地址
Go 官网下载地址:https://golang.org/dl/
Go 官方镜像站(推荐):https://golang.google.cn/dl/
安装
Windows 安装
将上一步选好的安装包下载到本地。
双击下载好的文件,然后按照提示步骤安装即可。
Linux 下安装
如果不是要在 Linux 平台敲 go 代码就不需要在 Linux 平台安装 Go,开发机上写好的 go 代码只需要跨平台编译好之后就可以拷贝到 Linux 服务器上运行了,这也是 go 程序跨平台易部署的优势。
wget https://dl.google.com/go/go1.17.1.linux-amd64.tar.gz
/usr/local
tar -zxvf go1.17.1.linux-amd64.tar.gz -C /usr/local # 解压
sudo/usr/local/
/etc/profile$HOME/.profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
/etc/profile$HOME/.profile$HOME/.profile
~ go version
go version go1.17.1 linux/amd64
Mac 下安装
/usr/local/go
检查
go version
配置 GOPATH
GOPATH
GOPATHGOPATHsrc
go modGOPATH
go modGOPATH
go modGOPATH
go mod
Linux 和 Mac 平台就参照上面配置环境变量的方式将自己的工作目录添加到环境变量中即可。 Windows 平台的步骤请自行 Google
GOPATHGOPATH
GOPATH 在不同操作系统平台上的默认值
平台 | GOPATH 默认值 | 举例 |
---|---|---|
Windows | %USERPROFILE%/go | C:\Users\用户名\go |
Unix | $HOME/go | /home/用户名/go |
GOROOTGOPATH
配置环境变量之后需要重启电脑上已经打开的终端。(例如 cmd、VS Code 里面的终端和其他编辑器的终端)。
Go 项目结构
不论采用何种编程语言,良好的项目组织结构都至关重要,因为这将直接影响项目内部依赖的复杂程度以及项目对外提供 API 等服务的灵活性等。最好在项目初期便制定好项目结构约定,甚至可以为其开发脚手架之类的工具来生成项目模板,让开发者尽量按照统一的规范参与项目。
项目的目录结构通常也是门面,内行人通过目录结构基本就能看出开发者是否有经验。 Go 官网并没有给出一个目录结构的标准模板,但是 golang-standards 倒是给出了一个,目录结构如下:
├── api
├── assets
├── build
│ ├── ci
│ └── package
├── cmd
│ └── *your_app*
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── init
├── internal
│ ├── app
│ │ └── *your_app*
│ └── pkg
│ └── *your_private_lib*
├── pkg
│ └── *your_public_lib*
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
│ ├── app
│ ├── static
│ └── template
├── website
├── .gitignore
├── LICENSE.md
├── Makefile
├── README.md
└── go.mod
这是 Go 应用程序项目的基本布局。它不是核心 Go 开发团队定义的官方标准;然而,它是 Go 生态系统中一组常见的老项目和新项目的布局模式。其中一些模式比其他模式更受欢迎。它还具有许多小的增强,以及对任何足够大的实际应用程序通用的几个支持目录。
此项目布局是通用的,并且不会尝试强加一个特定的 Go 包结构。
/cmd
本项目的主干。
/cmd/myapp
/pkg/internal
main/internal/pkg
/internal
release notesinternal
/internal/app/internal/app/myapp/internal/pkg/internal/pkg/myprivlib
/pkg
/pkg/mypubliclibinternal/pkgI'll take pkg over internalpkginternal
当根目录包含大量非 Go 组件和目录时,这也是一种将 Go 代码分组到一个位置的方法,这使得运行各种 Go 工具变得更加容易
/pkg
如果你的应用程序项目真的很小,并且额外的嵌套并不能增加多少价值(除非你真的想要:-),那就不要使用它。当它变得足够大时,你的根目录会变得非常繁琐时(尤其是当你有很多非 Go 应用组件时),请考虑一下。
/vendor
Go Modulesgo mod vendor/vendorgo build-mod=vendor
如果你正在构建一个库,那么不要提交你的应用程序依赖项。
1.13vendor
模块代理
服务应用程序目录
/api
OpenAPI/Swagger 规范,JSON 模式文件,协议定义文件。
/api
Web 应用程序目录
/web
特定于 Web 应用程序的组件:静态 Web 资产、服务器端模板和 SPAs。
通用应用目录
/configs
配置文件模板或默认配置。
confdconsul-template
/init
System init(systemd,upstart,sysv)和 process manager/supervisor(runit,supervisor)配置。
/scripts
执行各种构建、安装、分析等操作的脚本。
https://github.com/hashicorp/terraform/blob/master/Makefile
/scripts
/build
打包和持续集成。
/build/package
/build/ci/build/ci
/deployments
/deploy
/test
/test/test/data/test/testdata
/test
其他目录
/docs
设计和用户文档(除了 godoc 生成的文档之外)。
/docs
/tools
/pkg/internal
/tools
/examples
应用程序和/或公共库的示例。
/examples
/third_party
外部辅助工具,分叉代码和其他第三方工具(例如 Swagger UI)。
/githooks
Git hooks。
/assets
与存储库一起使用的其他资源(图像、徽标等)。
/website
如果你不使用 Github 页面,则在这里放置项目的网站数据。
/website
不应该拥有的目录
/src
src
srcsrcHow to Write Go Code$GOPATH$HOME/go/pkg/bin/src/src/src/some/path/to/workspace/src/your_project/src/your_code.goGOPATH
Go 开发编辑器
好的编辑器可以提高开发的效率,推荐两款目前最流行的编辑器。
第一是 Visual Studio Code + Go 扩展插件,可以非常高效地开发,通过官方网站 https://code.visualstudio.com/ 下载使用。
第二是老牌 IDE 公司 JetBrains 推出的 Goland,所有插件已经全部集成,更容易上手,并且功能强大,新手老手都适合,可以通过官方网站 https://www.jetbrains.com/go/ 下载使用。
第一个 Go 程序
go mod
hello
go mod init 执行成功后,会生成一个 go.mod 文件
main.go
package main // 声明 main 包,表明当前是一个可执行程序
import "fmt" // 导入内置 fmt 包
func main(){ // main函数,是程序执行的入口
fmt.Println("Hello World!") // 在终端打印 Hello World!
}
go build
go build
在 hello 目录下执行:
go build
或者在其他目录执行以下命令:
go build hello
GOPATHhello
hello.exe
-o
go build -o aaaaaaa.exe
go install
go installGOPATHGOPATH
跨平台编译
go build
SET CGO_ENABLED=0 // 禁用CGO
SET GOOS=linux // 目标平台是linux
SET GOARCH=amd64 // 目标处理器架构是amd64
使用了 cgo 的代码是不支持跨平台编译的
go build
Mac 下编译 Linux 和 Windows 平台 64 位 可执行程序:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
Linux 下编译 Mac 和 Windows 平台 64 位可执行程序:
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build
Windows 下编译 Mac 平台 64 位可执行程序:
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build