Go的第12课——包管理

包可以区分命令空间(一个文件夹中不能有两个同名文件),也可以更好的管理项目。go 中创建一个包,一般是创建一个文件夹,在该文件夹里面的 go 文件中,使用package关键字声明包名称,通常,文件夹名称和包名称相同。并且,同一个文件下面只有一包。

创建包

新建一个文件夹,文件夹名就是包名,在里面所有的 go 文件中加入一句 package xxx

比如我要创建一个 DAO 包。

1
2
3
4
5
6
7
package DAO

import "fmt"

func test() {
fmt.Println("DAO:Test")
}

导入包

要使用某个包下面的变量或者方法,需要导入该包,导入包时,要导入从 GOPATH 开始的包路径,例如,在 service.go 中导入 DAO 包,但是需要点小小的操作。

注意事项

  • 一个目录下只能有一个package
  • import 后面的其实是GOPATH 开始的相对目录路径,包括最后一段。但由于一个目录下只能有一个package,所以import 一个路径就等于是 import 了这个路径下的包。
  • 注意,这里指的是“直接包含”的go 文件。如果有子目录,那么子目录的父目录是完全两个包。
  • 一个package的文件不能在多个目录下。
  • 如果多个目录下有重名的package,它们其实是彼此无关的package。
  • 如果一个go文件需要同时使用不同目录下的同名package,需要在import这些目录时为每个目录指定一个package的别名。

包管理工具

go module 命令

go modules 是 golang 1.11 新加的特性,用来管理模块中包的依赖关系。

go mod 使用方法

初始化模块

1
go mod init <项目模块名称>

依赖关系处理,根据go.mod文件

1
go mod tidy

将依赖包复制到项目下的 vendor目录。

1
go mod vendor

如果包被屏蔽(墙),可以使用这个命令,随后使用go build-mod=vendor编译显示依赖关系

1
go list-m all

显示详细依赖关系

1
go list-m-json all

下载依赖

1
go mod download[path@version]

[path@version]是非必写的

实操一遍

目录架构为这样:

WWW 目录中运行 go mod init xia0ji233/WWW

进入 DAO 目录运行 go build

再出来目录运行 go mod tidy

我们就可以在 main.go 中引用这个包了。

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"
import "xia0ji233/WWW/DAO"

func main() {
fmt.Println("hello world")
DAO.Test()
}
/*
hello world
DAO:test
*/

这里可能遇到一个神坑的问题就是无法使用未导出的函数,这里需要解释一波就是

go中根据首字母的大小写来确定可以访问的权限。无论是方法名、常量、变量名还是结构体的名称,如果首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用。可以粗暴的理解为首字母大写是公有的,首字母小写是私有的。

所以我们被包含的包要使用里面定义的函数那就必须首字母大写。