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工具将编译和运行两个步骤合二为一:
$ 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中:
func 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.sh
source /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"