首页 > 其他 > 详细

Go包管理

时间:2020-10-28 09:12:06      阅读:30      评论:0      收藏:0      [点我收藏+]

Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案。Go语言中为我们提供了很多内置包,如 fmt、os、io 等。

任何源代码文件必须属于某个包,同时源码文件的第一行有效代码必须是package pacakgeName 语句,通过该语句声明自己所在的包。

包的基本概念

Go语言的包借助了目录树的组织形式,一般包的名称就是其源文件所在目录的名称,虽然Go语言没有强制要求包名必须和其所在的目录名同名,但还是建议包名和所在目录同名,这样结构更清晰。

包可以定义在很深的目录中,包名的定义是不包括目录路径的,但是包在引用时一般使用全路径引用。

包命名规范

包名小写字母,尽量短小。

包名一般要和所在的目录同名,也可以不同,包名中不能包含`-` 等特殊符号。

同一个文件夹所有go文件的包名必须一致

包名为 main 的包为应用程序的入口包,编译不包含 main 包的源码文件时不会得到可执行文件。

包的导入

单行导入

import "包1的路径"
import "包2的路径"

多行导入

import (
  "包 1 的路径"
  "包 2 的路径"
)

包4种引用格式

(1)标准引用格式

此时可以用fmt.作为前缀来使用 fmt 包中的方法,这是常用的一种方式。

import "fmt"

(2)自定义别名引用格式

import F "fmt"

其中 F 就是 fmt 包的别名,使用时我们可以使用F.来代替标准引用格式的fmt.来作为前缀使用 fmt 包中的方法。

(3)点引用格式

import . "fmt"

不用加前缀fmt.,直接引用。

(4)匿名引用格式

使用标准格式引用包,但是代码中却没有使用包,编译器会报错。如果包中有 init 初始化函数,则通过import _ "包的路径" 这种方式引用包,仅执行包的初始化函数,即使包没有 init 初始化函数,也不会引发编译器报错。

import _ "fmt"

匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中。

注意:
	(1)一个包可以有多个 init 函数,包加载时会执行全部的 init 函数,但并不能保证执行顺序,所以不建议在一个包中放入多个 init 函数,将需要初始化的逻辑放到一个 init 函数里面。
	(2)包不能出现环形引用的情况,比如包 a 引用了包 b,包 b 引用了包 c,如果包 c 又引用了包 a,则编译不能通过。
	(3)包的重复引用是允许的,比如包 a 引用了包 b 和包 c,包 b 和包 c 都引用了包 d。这种场景相当于重复引用了 d,这种情况(有向无环图)是允许的,并且 Go 编译器保证包 d 的 init 函数只会执行一次。

包加载过程

在执行 main 包的 mian 函数之前, Go 引导程序会先对整个程序的包进行初始化。整个执行的流程如下图所示:

技术分享图片

包管理两种方式之GOPATH

GOPATH环境变量、配置目录、项目开发目录

工作目录结构说明:

bin: 用于放置发布的二进制程序
pkg: 用于放置库文件,非main包编译结果
src: 用于放置源代码

包的导入路径

包的绝对路径就是GOROOT/src/GOPATH/src/或者gomod后面包的存放路径,现在一般使用gomod的方式

// GOPATH/src/database目录路径引用
// GOPATH/src/lab目录路径引用
import "lab/test"
import "database/sql/driver"
import "database/sql"

GOPATH支持相对路径导入

import "./gpkgname/pkg02"

GOPATH编译找包

GOPATH/src/pakeage

编译与运行

go build 编译二进制文件
go build GOPATHMAIN
编译路径GOPATH下的包main包,则在当前目录产生以GOPATHMAIN命名的二进制程序

go run 运行二进制文件

go install 编译并发布二进制文件
go install GOPATHMAIN
编译并发布路径GOPATHMAIN下的包,main包,则在将编译后的以GOPATHMAIN命名的二进制程序拷贝到bin目录

go install 编译发布库文件
go install GOPATHMAIN/pkg01
编译并发布路径GOPATHMAIN/pkg01下的包,非main包,则在将编译的以包名命名的库文件拷贝到 pkg/GOOS_GOARCH目录下

go install 编译发布所有二进制和库文件
go install ./…
编译并发布当前路径下的所有二进制程序和库文件,不允许交叉导入包

vendor

go 1.5版本推出的vendor

GOPATH项目目录下创建vendor目录 第三方包将下载拷贝到vendor

vendor使用顺序

当前a包中使用顺序
	a/vendor
    a/../vendor
    GOPATH/src/vendor
    GOPATH/src
    GOROOT/src

包升级

升级需要覆盖旧的vendor,不方便管理。所以go 1.11出现了go mod管理方式

第三方包

可以借助 go get 工具下载和安装第三方包及其依赖,需要安装与第三方包匹配的代码管理工具,比如 git、svn 等

常用参数:

-d:仅下载依赖包
-u:更新包并安装
-x:打印执行的命令
-v:打印构建的包
-insecure:允许使用 http 协议下载包

第三方包查找地址:

https://godoc.org

https://gowalker.org/

包管理两种方式之Go modules 机制

go 1.11推出了go modules机制

优势

不用设置 GOPATH,代码可任意放置

自动下载依赖管理

版本控制

不允许使用相对导入

replace 机制

是否开启gomod

go env -w GO111MODULE=on

GO111MODULE=off 无模块支持,go 会从 GOPATH 和 vendor 文件夹寻找包。必须GOPATH

GO111MODULE=on 模块支持,go 会忽略 GOPATH 和 vendor 文件夹,只根据 go.mod 下载依赖。必须go.mod

GO111MODULE=auto 自动选择,在 $GOPATH/src 外面且根目录有 go.mod 文件时,开启模块支持。否则使用 GOPATH 和 vendor 机制

初始化模块(项目名称)

go mod init modname

go modules模式包导入

import (
	"fmt"
	"modname/math"
    "modname/math/pkgb"
) // 模块名称/目录路径!!!

导入包顺序
	1、go标准包
    2、第三方包
    3、本地包

包4种引用格式

第三方包

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

replace 机制

go.mod文件方式

module testmod

go 1.14

replace (
	golang.org/x/net => github.com/golang/net v0.0.0-20180906233101-161cd47e91fd
)

命令行方式

go mod edit -replace=goland.org/x/net@latest=github.com/goland/net@latest // 编写代码还是goland,实际是github

require

go.mod文件

module testmod

go 1.14

replace (
	golang.org/x/net => github.com/golang/net v0.0.0-20180906233101-161cd47e91fd
)

require (
	github.com/astaxie/beego v1.12.2 // indirect
	github.com/imsilence/testmath v0.0.0-20201017035600-785fc3eb6ad9
) // 查看go.mod文件中自动添加的第三方模块和go.sum文件

go.sum文件

github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
省略...

常用命令

go mod tidy: 精简不依赖的库

go mod vendor: 将依赖模块拷贝到模块中的 vendor 目录,使用vender方式

go build: 编译当前模块

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

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

go mod edit : 编辑go.mod文件

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

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

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

go mod edit: 修改 go.mod 文件

? -require=pakcage@version

? -replace=old_package@version=new_package@version

? 可以使用-replace 功能将包替换为本地包,实现相对导入

外网不通的情况下

gitlab/gitee
1. 自己内网程序, 没有以来任何第三方库
2. 依赖内部其他团队提供的库
3. 依赖外网的第三方库
a. 编译环境 => 目标站点
=> acl
=> proxy <=> 镜像
=> 第三方包下载 => gitlab/gitee
replace

包可见性

首字母大写(变量和函数),包外可见
首字母小写(变量和函数),只能包内使用

包名和文件名不一样(不建议)

因为:

导入包:项目名称/目录
用包:包名.方法

Go包管理

原文:https://www.cnblogs.com/Otiger/p/13889004.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!