Go的编译原理
==待完善==
工程结构详述
一般的编程语言往往对工程(项目)的目录结构是没有什么规定的,但是Go语言却在这方面做了相关规定
如果想要构建一个项目,就需要将这个项目的目录添加到 GOPATH 中,多个项目之间可以使用 ; 分隔,如果不配置 GOPATH,即使处于同一目录,代码之间也无法通过绝对路径相互调用。
目录结构
一个Go语言项目的目录一般包含以下三个子目录
src 目录
重点关注,放置项目和库的源文件;
- 用于以包(package)的形式组织并存放 Go 源文件,这里的包与 src 下的每个子目录是一一对应。例如,若一个源文件被声明属于 log 包,那么它就应当保存在 src/log 目录中。
- 并不是说 src 目录下不能存放 Go 源文件,一般在测试或演示的时候也可以把 Go 源文件直接放在 src 目录下,但是这么做的话就只能声明该源文件属于 main 包了。正常开发中还是建议大家把 Go 源文件放入特定的目录中。
- 包是Go语言管理代码的重要机制,其作用类似于Java中的 package 和 C/C++ 的头文件。Go 源文件中第一段有效代码必须是package <包名>的形式,如 package hello。
- 另外需要注意的是,Go语言会把通过go get命令获取到的库源文件下载到 src 目录下对应的文件夹当中
pkg 目录
放置编译后生成的包/库的归档文件;
- 用于存放通过go install命令安装某个包后的归档文件。归档文件是指那些名称以“.a”结尾的文件。
- 该目录与 GOROOT 目录(也就是Go语言的安装目录)下的 pkg 目录功能类似,区别在于这里的 pkg 目录专门用来存放项目代码的归档文件。
- 编译和安装项目代码的过程一般会以代码包为单位进行,比如 log 包被编译安装后,将生成一个名为 log.a 的归档文件,并存放在当前项目的 pkg 目录下
bin 目录
放置编译后生成的可执行文件
* 与 pkg 目录类似,在通过go install命令完成安装后,保存由 Go 命令源文件生成的可执行文件。在类 Unix 操作系统下,这个可执行文件的名称与命令源文件的文件名相同。而在 Windows 操作系统下,这个可执行文件的名称则是命令源文件的文件名加 .exe 后缀
源文件
命令源文件
如果一个 Go 源文件被声明属于 main 包,并且该文件中包含 main 函数,则它就是命令源码文件。命令源文件属于程序的入口,可以通过Go语言的go run命令运行或者通过go build命令生成可执行文件。
库源文件
库源文件则是指存在于某个包中的普通源文件,并且库源文件中不包含 main 函数
Go语言依赖管理
==待完善==
第一个Go程序
新建一个 hello_world.go
1 | // 声明包 main是包名 |
代码详解
package(创建包)
Go语言以“包”作为管理单位,每个 Go 源文件必须先声明它所属的包,所以每个 Go 源文件的开头都是一个 package 声明
Go语言的包与文件夹是一一对应的,它具有以下几点特性:
- 一个目录下的同级文件属于同一个包。
- 包名可以与其目录名不同。
- main 包是Go语言程序的入口包,一个Go语言程序必须有且仅有一个 main 包。如果一个程序没有 main 包,那么编译时将会出错,无法生成可执行文件。
import(导入包)
在包声明之后,是 import 语句,用于导入程序中所依赖的包,导入的包名使用双引号””包围,格式如下
导入单个包
import “name”
导入多个包
import ( “fmt” “os” )
其中 import 是导入包的关键字,name 为所导入包的名字
另外有一点需要注意,导入的包中不能含有代码中没有使用到的包,否则Go编译器会报编译错误
main 函数
main函数是Go语言程序的入口函数,也即程序启动后运行的第一个函数。
一个 main 包中必须有且仅有一个 main 函数
main 函数是自定义函数的一种,在Go语言中,所有函数都以关键字 func 开头的,定义格式如下所示
1 | func 函数名 (参数列表) (返回值列表){ 函数体 } |
格式说明如下
函数名: 由字母、数字、下画线_组成,其中,函数名的第一个字母不能为数字,并且,在同一个包内,函数名称不能重名。
参数列表: 一个参数由参数变量和参数类型组成,例如func foo( a int, b string )。
返回值列表:可以是返回值类型列表,也可以是参数列表那样变量名与类型的组合,函数有返回值时,必须在函数体中使用 return 语句返回。
函数体: 能够被重复调用的代码片段
Go语言函数的左大括号{必须和函数名称在同一行,否则会报错
go程序的编译和运行
go build 命令
go build命令用来启动编译,它可以将Go语言程序与相关依赖编译成一个可执行文件,其语法格式如
1 | go build fileName [...] |
fileName 为所需要的参数,可以是一个或者多个 Go 源文件名(当有多个参数时需要使用空格将两个相邻的参数隔开),也可以省略不写
go build命令只有在执行出错的情况下才会有返回信息,执行成功的话是没有返回信息的,但是会在当前目录生成一个与 main 包文件同名的 .exe 可执行文件
使用 go build 命令进行编译时,不同参数的执行结果也是不同的。
1) 当参数不为空时
如果 fileName 为同一 main 包下的所有源文件名(可能有一个或者多个),编译器将生成一个与第一个 fileName 同名的可执行文件(如执行go build abc.go def.go …会生成一个 abc.exe 文件);
如果 fileName 为非 main 包下的源文件名,编译器将只对该包进行语法检查,不生成可执行文件。
2) 当参数为空时
如果当前目录下存在 main 包,则会生成一个与当前目录名同名的 目录名.exe 可执行文件(如在 hello 目录中执行go build命令时,会生成 hello.exe 文件);
如果不存在 main 包,则只对当前目录下的程序源码进行语法检查,不会生成可执行文件
go run 命令
除了使用go build命令外,Go语言还为我们提供了go run命令
go run命令将编译和执行指令合二为一,会在编译之后立即执行Go语言程序,但是不会生成可执行文件。
语法格式如下:
1 | go run fileName |
fileName 为所需要的参数,参数必须是同一 main 包下的所有源文件名,并且不能为空