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
2
3
4
5
6
7
8
9
10
// 声明包 main是包名
package main
//导入 fmt 包,打印字符串是需要用到。
//fmt 包是Go语言标准库为我们提供的,用于格式化输入输出的内容(类似于C语言中的 stdio.h 头文件),类似的还有 os 包、io 包等
import ( "fmt" )
// 声明 main 主函数
func main() {
fmt.Println("Hello World!")
// 打印 Hello World!
}

代码详解

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 包下的所有源文件名,并且不能为空