共计 5290 个字符,预计需要花费 14 分钟才能阅读完成。
这篇文章的内容主要围绕 Go 基础中如何构建 go 程序进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随丸趣 TV 小编一起阅读吧。希望大家通过这篇文章有所收获!
hello world
从一个简单的程序开始解释,将下面的内容放进 test.go 文件中,路径随意:
package main import (fmt) func main() { fmt.Println( Hello World)}
Go 通过包的方式管理程序,每个 Go 源代码文件都必须声明自己所在的包,正如上面的 package main 声明自己所在的包是 main 包。
每个程序都必须有一个 main 包,main 包作为整个程序的编译入口包,main 包中的 main()函数作为程序的执行入口。
import 关键字用来导入其它包,导入某个包之后就能在当前文件中使用这个包中的函数,例如上面的 main 包导入 fmt 包后,可以使用 fmt 包中的函数 Println()。
然后可以使用 go 的 build 工具编译这个 test.go 文件:
$ go build test.go
编译后,将在当前路径下生成一个可执行二进制文件:Windows 下生成的是 test.exe 文件,Unix 下生成的是 test 文件。既然是可执行文件,当然可以直接执行:
$ ./test
将输出 Hello World。
也可以直接通过 go 的 run 工具将编译和运行两个步骤合二为一:
2$ go run test.go Hello World
go run 不会生成可执行的二进制文件,它实际上是将编译得到的文件放进一个临时目录,然后执行,执行完后自动清理临时目录。
关于包和 go 文件
每个 go 代码文件只能且必须使用 package 语句声明一个包,也就是说一个文件中不能包含多个包。
Go 中有两种类型的包,或者说有两种类型的文件:
编译后成为可执行文件的包,也就是 main 包编译后的得到的文件
编译后成为共享库的包,只要 go 程序文件中声明的不是 main 包,就是库文件
注意:
在 go 的官方文档中将 go 的二进制可执行程序称为命令,有时候还会将 go 的源代码文件称为命令的源文件。可执行程序和包相反,包一般是作为 库 文件存在,用于导入而非用于执行
共享库中包含一些函数,这些函数比较通用,所以放进共享库方便函数复用。例如 fmt 包中的 Println 函数,到处都在使用这个函数,且因为 fmt 包是标准库(Standary library),无论是谁都可以去使用这个包。
有两种类型的库文件:标准库和第三方的库。标准库是随 Go 安装的时候放在 go 安装目录下的($GOROOT/src/),第三方库是放在 workspace 下的。关于 workspace 后文再说。
共享库可以被 import 导入(例如 fmt 包)。由于导入操作是在编译期间实现的,共享库中不应该包含任何输出型语句。
Go 中对库文件要求比较严格,或者说强制性的规范。它要求库文件中 package 声明的包名必须和目录名称相同,且同一个目录下只允许有一个包,但同一个目录下可以有多个库文件片段,只不过这些库文件中必须都使用 package 声明它的包名为目录名。例如:
src/mycode
|- first.go |- second.go |- third.go
如果这三个文件都是库文件,则它们都必须且只能使用 package mycode 声明自己的包为 mycode。go build 的时候,会将它们合并起来。如果声明的包名不是 mycode,go build 会直接忽略它。
当然,对 main 包就无所谓了,它不是库文件,可以放在任何地方,对目录名没有要求。但如果使用 go install,则有额外的要求,见后文。
库文件中的大小写命名
Go 通过名称首字母的大小写决定属性是否允许导出:
首字母大写的属性是允许导出的属性首字母小写的属性不允许被导出
所以当库文件被导入时,只有这个库文件中以大写字母开头的常量、变量、函数等才会被导出,才可以在其他文件中使用。
例如,库文件 abc.go 中:
2func first() {} func Second() {}
当导入这个包的时候,由于 first()函数首字母小写,外界无法使用它,它只能在自己的包 abc.go 中使用,对外界不可见。大写字母开头的 Second()函数会被导入,所以可用。
工作空间 (workspace) 速览
通过环境变量 GOPATH 设置 workspace 的路径 Go 编程人员一般将它们的 Go 代码放在一个 workspace 下,当然,这不是必须的 workspace 包含一个或多个版本控制系统的仓库 (如 git) 每个仓库包含一个或多个 package 每个 package 由单个目录下的一个或多个 Go 源文件组成,它们都必须声明目录名作为它们的包名 package 的目录路径决定导入包时 import 的路径
Go 和其它编程语言在组织项目的时候有所不同,其它语言一般每个项目都有一个单独的 workspace,且 workspace 一般和版本控制仓库进行绑定。
现在设置 GOPATH 环境变量,假设设置为 /gocode
echo export GOPATH=/gocode /etc/profile.d/gopath.sh
chmod +x /etc/profile.d/gopath.shsource /etc/profile.d/gopath.sh
go env GOPATH 确定是否正确:
$ go env GOPATH /gocode
workspace 目录结构
每个 workspace 都是一个目录,这个目录下至少包含三个目录:
src:该目录用于存放 Go 源代码文件(也称为命令的源文件)bin:该目录用于存放可执行命令(即构建后可执行的二进制 go 程序,也称为命令文件)pkg:该目录用于存放共享库文件(即构建后非可执行程序的库包,也称为包对象文件)
括号中给的名称是 go 官方文档中常见的别名称呼。
所以,先创建这 3 个目录
mkdir -p /gocode/{src,pkg,bin}
GOPATH 和 GOROOT 环境变量
GOPATH 环境变量指定 workspace 的位置,用来指示 go 从哪里搜索 go 源文件 / 包,例如 import 时从哪个路径搜索包并导入。GOROOT 环境变量用于指定 go 的安装位置。go 需要导入包时,会从 GOPATH 和 GOROOT 所设置的位置处搜索包。
默认位置为 $HOME/go(Unix)或 %USERPROFILE\go%(Windows)。可以手动设置 GOPATH 环境变量的路径从而指定 workspace 的位置,可以指定为多个目录,多个目录时使用冒号分隔目录 (Unix 系统) 或使用分号分隔目录(Windows 系统)。注意,绝对不能将其设置为 go 的安装目录,即不能和 GOROOT 环境变量重复。
例如,windows 下设置 d:\gocode 目录为 GOPATH 的路径:
setx GOPATH d:\gocode
Unix 下设置 $HOME/gocode 目录为 GOPATH 的路径:
mkdir ~/gocode export GOPATH=~/gocode echo GOPATH=~/gocode ~/.bashrc
go env 或 go env GOPATH 命令可以输出当前有效的 GOPATH 路径。
$ go env | grep GOPATH GOPATH= /root/gocode $ go env GOPATH /root/gocode
go build
先写两个 go 文件,一个是可执行 go 文件 test.go,一个是共享库 strutils.go,将它们放在 workspace 的 src 下。
$ mkdir -p $GOPATH/src/{hello,strutils} $ tree -C .├── bin├── pkg├── src│ ├── hello│ │ └── test.go│ └── strutils│ └── strutils.go
注意,上面故意将 test.go 放在名为 hello 的目录下,可以将其放在 src 下的任何非库文件目录下(例如不能放进 strutils 目录下),名称不要求。
hello/test.go 的内容如下:
package main import (fmt strutils) func main() { fmt.Println( Hello World) fmt.Println(strutils.ToUpperCase( hello world))}
strutils/strutils.go 的内容如下:
package strutils import (strings) func ToUpperCase(s string) string{return strings.ToUpper(s)} func ToLowerCase(s string) string{return strings.ToLower(s)}
go build 可以用于编译,编译时会对 import 导入的包进行搜索,搜索的路径为标准库所在路径 $GOROOT/src、workspace 下的 src 目录。它只会生成额外的可执行文件放在当前目录下,不会生成额外的库文件。但需要注意,生成的可执行文件名称可能会出乎意料:
例如进入到目录 src/hello 下,对 test.go 的文件进行编译,以下三种 build 路径都可用成功编译:
cd src/hello go build
# 生成的可执行文件名为 hello go build .
# 生成的可执行文件名为 hello go build test.go
# 生成的可执行文件名为 test
前两者是等价的,当 go build 以目录的形式进行编译,则生成的可执行文件名为目录名。当 go build 以 go 代码文件名的方式进行编译,则生成的可执行程序名为 go 源码文件名(去掉后缀.go 或增加后缀.exe)。
go install
go 还有一个工具 install,go install 的操作称为安装,将文件安装到合适的位置。go install 时会先进行编译,然后将编译后的二进制文件保存到 workspace 的 bin 目录下,将编译后的库文件 (称为包对象文件,以 .a 为后缀) 放在 pkg 目录下。
注意,go install 时必须先进入到 $GOPATH/src 下,且只能对目录进行操作,不能对具体的 go 文件操作,因为 go 认为包和目录名相同。给 go install 指定一个目录名,就表示编译这个包名。
例如,对 src/hello 下的 test.go 进行安装,由于它导入了 strutils 包,所以会自动将 strutils 也安装好:
$ cd $GOPATH/src $ go install hello $ tree $GOPATH /gocode├── bin│ └── hello # 二进制程序文件名为 hello,而非 test├── pkg│ └── linux_amd64 │ └── strutils.a # 库文件└── src ├── hello │ └── test.go └── strutils └── strutils.go
还可以单独对库文件进行安装:
$ rm -rf $GOPATH/bin/* $GOPATH/pkg/* $ cd $GOPATH/src $ go install strutils /gocode├── bin├── pkg│ └── linux_amd64│ └── strutils.a└── src ├── hello │ └── test.go └── strutils └── strutils.go
如果省略目录名,则表示对当前目录下的包进行安装:
$ cd $GOPATH/src/hello $ go install
再次提醒,go install 前先进入到 $GOPATH/src 目录下。
由于 go install 可以直接安装二进制文件到 $GOPATH/bin,所以出于方便执行这些二进制程序,可以将这个目录放进 PATH 环境变量。
$ export PATH=$PATH:`go env GOPATH`/bin
构建 go 程序的规范建议
1. 由于可以将所有 go 项目放在同一个 $GOPATH 目录下,为了区分 src 下的项目目录和库文件目录,建议将每个项目目录设置深一点。
例如:
binpkgsrc |- /first/project |- main.go |- myliba |- a.go |- b.go |- mylibb |- c.go |- d.go |- /second/project |- main.go |- lib |- a.go |- b.go
2.go install 时,先进入到项目目录下。
3. 库文件的名称 (也是目录名) 要选取合理,尽量短,但却尽量见名知意,也尽量减少名称重复的几率。
例如 util 这种名称到处都是,可以修改为 numutil、nameutil 等。
什么是 go
go 是 golang 的简称,golang 是 Google 开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,其语法与 C 语言相近,但并不包括如枚举、异常处理、继承、泛型、断言、虚函数等功能。
感谢你的阅读,相信你对“Go 基础中如何构建 go 程序”这一问题有一定的了解,快去动手实践吧,如果想了解更多相关知识点,可以关注丸趣 TV 网站!丸趣 TV 小编会继续为大家带来更好的文章!