目录

一 包的使用

1.1 package与import

在实际的开发中,我们往往需要在不同的文件中,去调用其它文件的定义的函数,比如 main.go 中,需要使用"fmt"包中的Println()函数:

package main
import "fmt"

在Go中,Go的每一个文件都属于一个包,也就是说Go是以包的形式来管理文件和项目目录结构。

如果要导入某些第三方包,直接输入包所在地址即可。文件的包名通常和文件所在的文件夹名一致,一般为小写字母。

  • package 指令在 文件第一行,然后是 import 指令

  • 在 import 包时,路径从 $GOPATH 的 src 下开始,不用带 src , 编译器会自动从 src 下开始引入

  • 为了让其它包的文件,可以访问到本包的函数,则该函数名的首字母需要大写,类似其它语言 的 public ,这样才能跨包访问

  • 在访问其它包函数,变量时,其语法是 包名.函数名

导入包有两种书写方式:

  • import "myproject/lib": mypeoject是项目文件夹名,这里类似于绝对路径的写法

  • import "./lib":相对路径方式

多个包导入可以使用:

import (
    "包名"
    "包名" 
)

推荐:一般包名为全小写格式,且使用一个简短的命名。

1.2 GOPATH

GOPATH与GROOT:

GOROOT: Go的安装目录,比如c:/Go
GOPATH: Go的项目目录

GoPath目录用来存放代码文件、可运行文件、编译后的包文件。 1.1-1.7版本必须设置,而且不能和Go的安装目录一样,1.8版本后会有默认值:

Unix:$HOME/go
Windows:%USERPROFILE%/go。

GOPATH允许多个目录,多个目录的时候Windows是分号,Linux系统是冒号隔开。当有多个GOPATH时,默认会将go get的内容放在第一个目录下,$GOPATH 目录约定有三个子目录:

  • src:存放源代码,一般一个项目分配一个子目录;

  • pkg:编译后生成的文件,如.a文件

  • bin:编译后生成的可执行文件,可以加入$PATH中

注意:一般建议package的名称和目录名保持一致

1.3 包中的函数调用方式

函数调用的方式:

  • 同包下:直接调用即可

  • 不同包下:包名.函数名

注意:Go中,大写字母开头的变量是可导出的,也就是其它包可以读取的,是公有变量;小写字母开头的就是不可导出的,是私有变量。

1.4 init函数 与 _

init()函数在包加载时就会默认最先调用,用来对包中的一些属性进行初始化操作:

package util

import "fmt"

func init(){
    fmt.Println("初始化操作...")
}

有些情况下,我们在加载包时,并不是要使用包内的函数,而是想调用其初始化方法,可以这样引入包:

import _ "package1"

一个go包可以拥有读个init函数,会按照包中不同文件名顺序、同文件名中init函数前后顺序依次调用。

1.5 点操作

点语法在使用包调用函数时,可以省略包名:

import . "fmt"

Println("无需包名即可调用...")

不推荐该使用方式。

1.6 包别名

import p1 "package1"        // 此时包 package1 可以在代码中使用 p1 代替    

二 下载第三方包

go有很多优秀的第三方包,可以使用 go get 包地址来下载,下载的包会默认安装在Gopath目录中的src文件夹中。

Gopath支持多个目录,go get默认都会将包下载到配置的第一个gopath中。

三 包的加载

在程序执行前,Go引导程序会先对整个程序的包进行初始化:

  • 包初始化程序从 main 函数引用的包开始,逐级查找包的引用,直到找到没有引用其他包的包,最终生成一个包引用的有向无环图

  • Go 编译器会将有向无环图转换为一棵树,然后从树的叶子节点开始逐层向上对包进行初始化

  • 单个包的初始化中,先初始化常量,然后是全局变量,最后执行包的init 函数(如果有)

四 包的管理(已过时,推荐Go1.11后的go mod)

4.1 vendor

vendor机制是指在保重加入了一个额外的vendor目录,将依赖的外部包复制到vendor目录下(nodejs???),编译器在查找外部依赖包时,查找顺序是:

  • 优先在vendor目录下查找

  • 如果当前包目录下没有vendor目录,则沿着当前包向上级目录查找vendor目录,直到$GOPATH/src下的vendor目录

  • 如果还没有vendor,则查找GOPATH下的依赖包

  • 最后查找GOROOT下的依赖包

Go1.5中的版本机制,需要手动设置 GOl 5VENDOREXPERIMENT=1后编译器才能启用,Go1.6后默认支持开启vendor目录查找。

vendor的问题是在使用go get -u更新时,会将工程默认分支的最新版本拉取到本地,不能指定第三方包的版本。

4.2 dep

dep可以解决第三方包版本问题:

# dep安装
go get -u github.com /golang/dep/cmd/dep

# 测试
dep version

# 初始化一个项目
dep init

dep 通过两个元文件来管理依赖 :

  • Gopkg.toml:manifest 文件 ,可以由用户自由配置,包括依赖的 source 、 branch 、 version 等。可以通过命令产生,也可以被用户手动修改。

  • Gopkg .lock:lock 文件,仅描述工程当前第三方包版本视图,lock 是自动生成的,不可以手动修改。

同样 vendor 目录下存放具体依赖的外部包的代码。