包是函数和数据的集合,将有相关特性的函数和数据放在统一的文件/目录进行管理,每个 包都可以作为独立的单元维护并提供给其他项目进行使用

1.声明

Go源文件都需要在开头使用 package 声明所在包,包名告知编译器哪些是包的源代码用于编译库文件,其次包名用于限制包内成员对外的可见性,最后包名用于在包外对公开成员的访问。

包名使用简短的小写字母,常与所在目录名保持一致,一个包中可以由多个Go源文件,但必须使用相同包名。

2.导入&调用

在使用包时需要使用import将包按路径名导入,再通过包名调用成员,可通过import每行导入一个包,也可使用括号包含所有包并使用一个import导入

包 - 图1

工作目录结构说明:

  • bin: 用于放置发布的二进制程序;
  • pkg: 用于放置发布的库文件;
  • src: 用于放置源代码;

编译&运行:

  • 使用 go build 编译二进制文件
    命令:go build gpkgmain
    说明:编译路径gpkgmain下的包,main包,则在当前目录产生以pkgmain命令的二进制程序

  • 使用 go run 运行二进制文件
    命令:go run gpkgmain

  • 使用 go install 编译并发布二进制文件
    命令:go install pgkgmain
    说明:编译并发布路径gpkgmain下的包,main包,则在将编译后的以pkgmain命令的二进制程序拷贝到bin目录

  • 使用 go install 编译发布库文件
    命令:go install gpkgname/pkg01
    说明:编译并发布路径pgkgname/pkg01下的包,非main包,则在将编译的以包名命名的库文件拷贝到pkg/GOOS_GOARCH目录下

  • 使用 go install 编译发布所有二进制和库文件
    命令:go install ./…
    说明:编译并发布当前路径下的所有二进制程序和库文件
    注意:Go语音不允许交叉导入包

3.导入形式

  1. 绝对路径倒入,在GOPATH目录中查找包:import "fmt" import "gpkgname/pgk01"
  1. 相对路径导入,在当前文件所在的目录查找import "./gpkgname/pkg02"
  1. 点导入,在调用点导入包中的成员时可以直接使用成员名称进行调用(省略包名)``` package main

import . “fmt”

func main() { Println(“Hi”) }

  1. 4. 别名导入,当导入不通路径的相同包名时,可以别名导入为包重命名,避免冲突

pakcage main

import f “fmt”

func main() { f.Println(“hi”) }

  1. 5. 下划线导入,Go不允许导入但未使用,在某些情况下需要初始化包,使用空白符作为别名进行导入,从而使用包中的初始化函数可以执行:

package main

import _ “fmt”

func main() {

}

  1. <a name="af0ad68b"></a>
  2. ### 4.成员可见性
  3. Go语言使用名称首字母大小写来判断对象(常量、变量、函数、类型、结构体、方法等)的访问权限,首字母大写标识包外可见(公开的),否者仅包内可访问(内部的)

pakcage pkg01

// public var Name string = “pkg01”

// private var version string = “1.0” ```

5.main包与main函数

main包用于声明告知编译器将包编译为二进制可执行文件,在main包中的main函数是程序的入口,无返回值,无参数

6.init函数

init函数是初始化包使用,无返回值,无参数。建议每个包只定义一个。init函数在import包时自动被调用(const —> var —> init)

7.Go包管理

7.1 介绍

Go1.11版本提供Go modules机制对包进行管理,同时保留GOPATH和vendor机制,使用临时环境变量GO111MODULE进行控制,GO111MODULE有三个可选值:

  • 当GO111MODULE为off时,构建项目始终在GOPATH和vendor目录搜索目标程序依赖包;
  • 当GO111MODULE为on时,构建项目则始终使用Go modules机制,在GOPATH/pkg/mod目录搜索目标程序依赖包;
  • 当GO111MODULE为auto(默认)时,当构建源代码不在GOPATH/src的子目录且包含go.mod文件,则使用Go modules机制,否则使用GOPATH和vendor机制

7.2 GOPATH+vendor机制

  • vendor
    将项目依赖包拷贝到项目下的vendor目录,在编译时使用项目下vendor目录中的包进行编译,解决问题:

    • 依赖外部包过多,在使用第三方包时需要使用go get进行下载
    • 第三方包在go get下载后不能保证开发和编译时版本的兼容性
  • 包搜索顺序

    • 在当前包下的vendor目录查找
    • 向上级目录查找,知道GOPATH/src/vendor目录
    • 在GOPATH目录查找
    • 在GOROOT目录查找
  • 第三方包
    可以借助go get工具下载和安装第三方包及其依赖,需要安装与第三方包匹配的代码管理工具,比如git、svn等;
    常用参数:

7.3 Go modules机制

优势:

  • 不用设置GOPATH,代码可任意放置
  • 自动下载依赖管理
  • 版本控制
  • 不允许使用相对导入
  • replace机制

初始化模块:go mod init modname

对于当前模块下的包导入时需要使用modname+packagename

第三方包:在使用go mod tidy、go build、go test、go list命令会自动将第三方依赖写入到go.mod文件中同时下载第三方依赖包到GOPATH/pkg/mod/cache目录,并在当前模块目录生成一个构建状态跟踪文件go.sum,文件中记录当前module所有的顶层和间接依赖,以及这些依赖的校验和;

常用命令:

  • go mod tidy: 整理依赖模块(添加新增的,删除未使用的)

  • go mod vendor: 将依赖模块拷贝到模块中的vendor目录

  • go build: 编译当前模块

  • go build ./…: 编译当前目录下的所有模块

  • go build -mod=vendor: 使用当前模块下的vendor目录中的包进行编译

  • go mod download: 仅下载第三方模块

  • go mod grapha: 打印所有第三方模块

  • go list -m -json all: 显示所有模块信息

  • go mod edit: 修改go.mod文件
    -require=package@version
    -replace=old_package@version=new_package@version
    可以使用-replace功能将包替换为本地包,实现相对导入

8.标准包

Go提供了大量标准包,可查看:https://golang.google.cn/pkg

  • godoc工具:使用godoc命令可以在本地启动golang网站,用户本地查看帮助手册
  • go list std: 查看所有标准包
  • go doc packagename: 查看包的帮助信息
  • go doc packagename.element: 查看包内成员帮助信息