从一个简单的程序开始解释,将下面的内容放进test.go文件中,路径随意:linux
package main import ( "fmt" ) func main() { fmt.Println("Hello World") }
Go经过包的方式管理程序,每一个Go源代码文件都必须声明本身所在的包,正如上面的package main
声明本身所在的包是main包。git
每一个程序都必须有一个main包,main包做为整个程序的编译入口包,main包中的main()函数做为程序的执行入口。编程
import关键字用来导入其它包,导入某个包以后就能在当前文件中使用这个包中的函数,例如上面的main包导入fmt包后,可使用fmt包中的函数Println()。windows
而后可使用go的build工具编译这个test.go文件:bash
$ go build test.go
编译后,将在当前路径下生成一个可执行二进制文件:Windows下生成的是test.exe文件,Unix下生成的是test文件。既然是可执行文件,固然能够直接执行:编程语言
$ ./test
将输出"Hello World"。函数
也能够直接经过go的run工具将编译和运行两个步骤合二为一:工具
$ go run test.go Hello World
go run
不会生成可执行的二进制文件,它其实是将编译获得的文件放进一个临时目录,而后执行,执行完后自动清理临时目录。ui
每一个go代码文件只能且必须使用package语句声明一个包,也就是说一个文件中不能包含多个包。spa
Go中有两种类型的包,或者说有两种类型的文件:
注意:
在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()函数会被导入,因此可用。
GOPATH
设置workspace的路径workspace
下,固然,这不是必须的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都是一个目录,这个目录下至少包含三个目录:
括号中给的名称是go官方文档中常见的别名称呼。
因此,先建立这3个目录
mkdir -p /gocode/{src,pkg,bin}
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文件,一个是可执行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
时会先进行编译,而后将编译后的二进制文件保存到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
1.因为能够将全部go项目放在同一个$GOPATH
目录下,为了区分src下的项目目录和库文件目录,建议将每一个项目目录设置深一点。
例如:
bin pkg src |- /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等。