创建hello, world
程序
创建hello, world
文件夹
1 |
|
编写和运行第一个Go
程序
首先,我们需要创建一个名为 main.go 的源文件。
Go 源文件总是用全小写字母形式的短小单词命名,并且以.go 扩展名结尾。
如果要在源文件的名字中使用多个单词,我们通常直接是将多个单词连接起来作为源文件名,而不是使用其他分隔符,比如下划线。也就是说,我们通常使用 helloworld.go 作为文件名而不是 hello_world.go。
1 |
|
保存文件,编译和运行
1 |
|
hello, world
程序的结构
上述代码可以分成三部分剖析:
package main
这一行代码定义了 Go 中的一个包 package。包是 Go 语言的基本组成单元,通常使用单个的小写单词命名,一个 Go 程序本质上就是一组包的集合。所有 Go 代码都有自己隶属的包,在这里我们的“hello,world”示例的所有代码都在一个名为 main 的包中。main 包在 Go 中是一个特殊的包,整个 Go 程序中仅允许存在一个名为 main 的包
main 函数
1
2
3
4
func main() {
fmt.Println("hello, world")
}这里的 main 函数会比较特殊:当你运行一个可执行的 Go 程序的时候,所有的代码都会从这个入口函数开始运行。
import “fmt”
import “fmt” 一行中“fmt”代表的是包的导入路径(Import),它表示的是标准库下的 fmt 目录,整个 import 声明语句的含义是导入标准库 fmt 目录下的包;
fmt.Println 函数调用一行中的“fmt”代表的则是包名。
导入多个包可以使用圆括号
1
2
3
4import (
"fmt"
"strings"
)
Go
语言中程序是怎么编译的
Go 是一种编译型语言,这意味着只有你编译完 Go 程序之后,才可以将生成的可执行文件交付于其他人,并运行在没有安装 Go 的环境中。
1 | go build main.go |
当然,Go 也借鉴了动态语言的一些对开发者体验较好的特性,比如基于源码文件的直接执行,Go 提供了 run 命令可以直接运行 Go 源码文件,比如我们也可以使用下面命令直接基于 main.go 运行:
1 | go run main.go |
复杂项目下Go
程序的编译
我们新建一个项目:
1 |
|
在hellomodule
文件夹中创建并编辑main.go
文件
1 |
|
对于复杂项目的构建,我们采用 Go module
Go module 构建模式是在 Go 1.11 版本正式引入的,为的是彻底解决 Go 项目复杂版本依赖的问题,在 Go 1.16 版本中,Go module 已经成为了 Go 默认的包依赖管理机制和 Go 源码构建机制。
Go Module 的核心是一个名为 go.mod 的文件,在这个文件中存储了这个 module 对第三方依赖的全部信息。
通过 init
来创建go.mod
文件:
1 |
|
让我们看看生成的go.mod
文件中有什么:
1 |
|
其实,一个 module 就是一个包的集合,这些包和 module 一起打版本、发布和分发。go.mod 所在的目录被我们称为它声明的 module 的根目录。不过呢,这个时候的 go.mod 文件内容还比较简单,第一行内容是用于声明 module 路径(module path)的。而且,module 隐含了一个命名空间的概念,module 下每个包的导入路径都是由 module path 和包所在子目录的名字结合在一起构成。比如,如果 hellomodule 下有子目录 pkg/pkg1,那么 pkg1 下面的包的导入路径就是由 module path(github.com/alexhuihui/hellomodule)和包所在子目录的名字(pkg/pkg1)结合而成,也就是 github.com/alexhuihui/hellomodule/pkg/pkg1。另外,go.mod 的最后一行是一个 Go 版本指示符,用于表示这个 module 是在某个特定的 Go 版本的 module 语义的基础上编写的。
通过 go mod tidy
,让 Go
工具自动添加依赖
1 | $ go mod tidy |
下载依赖的时候你可能会碰上超时的问题,执行以下命令即可:
1 | $ go env -w GOPROXY=https://goproxy.cn,direct |
go mod tidy
执行之后,go.mod
就变成了这个样子:
1 | module github.com/bigwhite/hellomodule |
这个时候,go.mod 已经记录了 hellomodule 直接依赖的包的信息。不仅如此,hellomodule 目录下还多了一个名为 go.sum 的文件,这个文件记录了 hellomodule 的直接依赖和间接依赖包的相关版本的 hash 值,用来校验本地包的真实性。在构建的时候,如果本地依赖包的 hash 值与 go.sum 文件中记录的不一致,就会被拒绝构建。
有了 go.mod 以及 hellomodule 依赖的包版本信息后,我们再来执行构建:
1 |
|
成功构建后,执行main
命令,然后新开一个窗口执行curl localhost:9090/foo/bar
1 | $ ./main |
总结
Go 包是 Go 语言的基本组成单元。一个 Go 程序就是一组包的集合,所有 Go 代码都位于包中;
Go 源码可以导入其他 Go 包,并使用其中的导出语法元素,包括类型、变量、函数、方法等,而且,main 函数是整个 Go 应用的入口函数;
Go 源码需要先编译,再分发和运行。如果是单 Go 源文件的情况,我们可以直接使用 go build 命令 +Go 源文件名的方式编译。不过,对于复杂的 Go 项目,我们需要在 Go Module 的帮助下完成项目的构建。
原文链接: https://alexhuihui.github.io/article/20220125.html
版权声明: 转载请注明出处.