首页 > 其他分享 >十一、包管理

十一、包管理

时间:2022-12-21 23:44:58浏览次数:37  
标签:十一 管理 Go init api go import mod

十一、包管理

11.1、package

Go语言是使用包来组织源代码的,包(package)是多个 Go 源码的集合,是一种高级的代码复用方案。Go语言中为我们提供了很多内置包,如 fmt、os、io 等。任何源代码文件必须属于某个包,同时源码文件的第一行有效代码必须是package pacakgeName 语句,通过该语句声明自己所在的包。

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

11.1.1、包的基本使用

导入包的语法:

import "包的路径"    // 双引号

导入包路径规则:

Go 程序首先在 GOROOT/src 目录中寻找包目录,如果没有找到,则会去 GOPATH/src 目录中继续寻找。比如 fmt 包是位于 GOROOT/src 目录的 Go 语言标准库中的一部分,它将会从该目录中导入。

目录结构

db包

package db

import "fmt"

func HandleMySQL() {
    fmt.Println("操作MySQL数据库")
}
package db

import "fmt"

func HandleRedis() {
    fmt.Println("操作redis数据库")
}

api包

package api

import "fmt"
import "mysite/db"

func RestfulAPI() {
    db.HandleMySQL()
    fmt.Println("RestfulAPI:MySQL数据接口")
}
package api

import "fmt"
import "mysite/db"

func RpcAPI() {
    db.HandleRedis()
    fmt.Println("RpcAPI:redis数据接口")
}

main

package main

import "mysite/api"

func main() {
    // db.HandleMySQL()
    // db.HandleRedis()

    api.RestfulAPI()
    api.RpcAPI()

}

1、包名一般是小写的,见名知意,包名中不能包含等特殊符号。

2、包名规范上要和所在的目录同名,也可以不同。比如package api改为package newApi,代码改动为

package main

import newApi "mysite/api"

func main() {
  newApi.RestfulAPI()
  newApi.RpcAPI()
}

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

4、一个文件夹下的所有源码文件只能属于同一个包,同样属于同一个包的源码文件不能放在多个文件夹下。

5、一个包下的不同文件不能含有同名函数。

6、如果想在一个包中引用另外一个包里的标识符(如变量、常量、类型、函数等)时,该标识符必须是对外可见的(public),在Go语言中只需要将标识符的首字母大写就可以让标识符对外可见了。

7、环境变量GO111MODULE=off: go env -w GO111MODULE=off

8、将mysite剪切到src外的任何位置,都会导包失败。

11.1.2、包的导入格式

// 一次导入多个包
import (
    "fmt"
    "mysite/api"
)

// 设置包的别名
import F "fmt"

// 省略引用格式
import . "mysite/api"
RestfulAPI()

// 匿名导入 :在引用某个包时,如果只是希望执行包初始化的 init 函数,而不使用包内部的数据时,可以使用匿名引用格式
import _ "包名"
import (
      "database/sql"
      _ "github.com/go-sql-driver/mysql"
  )  

11.1.3、包的加载顺序

init()函数会在每个包完成初始化后自动执行,并且执行优先级比main函数高。

init 函数通常被用来:

  • 对变量进行初始化
  • 检查/修复程序的状态
  • 注册
  • 运行一次计算

注意:

1、一个包可以有多个 init 函数,包加载时会执行全部的 init 函数,但并不能保证执行顺序,所以不建议在一个包中放入多个 init 函数,将需要初始化的逻辑放到一个 init 函数里面。

2、包不能出现环形引用的情况,比如包 a 引用了包 b,包 b 引用了包 c,如果包 c 又引用了包 a,则编译不能通过。

3、包的重复引用是允许的,比如包 a 引用了包 b 和包 c,包 b 和包 c 都引用了包 d。这种场景相当于重复引用了 d,这种情况是允许的,并且 Go 编译器保证包 d 的 init 函数 只会执行一次

4、init()函数没有参数也没有返回值。 init()函数在程序运行时自动被调用执行,不能在代码中主动调用它。

 

11.2、go module

module是一个相关Go包的集合,它是源代码更替和版本控制的单元。

11.2.1、Go mod命令

download    download modules to local cache (下载依赖的module到本地cache))
edit        edit go.mod from tools or scripts (编辑go.mod文件)
graph       print module requirement graph (打印模块依赖图))
init        initialize new module in current directory (再当前文件夹下初始化一个新的module, 创建go.mod文件))
tidy        add missing and remove unused modules (增加丢失的module,去掉未用的module)
vendor      make vendored copy of dependencies (将依赖复制到vendor下)
verify      verify dependencies have expected content (校验依赖)
why         explain why packages or modules are needed (解释为什么需要依赖)

Mod Cache 路径默认在$GOPATH/pkg 下面:$GOPATH/pkg/mod

11.2.2、go mod流程

同样是mysite项目,现在从src中剪切到其它任何位置,会编译报错。用go module来解决这个问题。

(1) 首先将你的版本更新到最新的Go版本(>=1.11)

(2)通过go命令行,进入到你当前的工程目录下,在命令行设置临时环境变量go env -w GO111MODULE=off

(3)go mod init在当前目录下生成一个go.mod文件,执行这条命令时,当前目录不能存在go.mod文件(有删除)。

go mod init xxx  // xxx即声明的模块名

该命令在当前目录下生成go.mod文件,文件中声明了模块名称。

module xxx
go 1.16

以后相关依赖可以声明在这里,就像python的requirements

此时运行程序,会将相关的依赖直接下载到GOPATH/pkg/mod路径下。

(4)执行go mod tidy命令,它会添加缺失的模块以及移除不需要的模块

执行后会生成go.sum文件(模块下载条目)。添加参数-v,例如go mod tidy -v可以将执行的信息,即删除和添加的包打印到命令行;

将拉取的依赖存放到GOPATH/pkg/mod路径下。

(5)执行命令go mod verify来检查当前模块的依赖是否全部下载下来,是否下载下来被修改过。如果所有的模块都没有被修改过,那么执行这条命令之后,会打印all modules verified

(6)执行命令go mod vendor生成vendor文件夹,用来区分某些库的不同版本。该文件夹下将会放置你go.mod文件描述的依赖包,文件夹下同时还有一个文件modules.txt,它是你整个工程的所有模块。在执行这条命令之前,如果你工程之前有vendor目录,应该先进行删除。同理go mod vendor -v会将添加到vendor中的模块打印出来;

 

 

内部包调用从初始化模块名go.mod所在的目录开始查找,所以导入api包:import "xxx/api"

标签:十一,管理,Go,init,api,go,import,mod
From: https://www.cnblogs.com/xiaohaoge/p/16862705.html

相关文章

  • [vue项目] 后台管理 11111111111111111
    文章目录​​gitee地址​​​​登录业务解析​​​​退出登录​​​​模板结构图​​​​路由的搭建​​​​品牌管理​​​​table数据渲染​​​​分页器​​​​点击添加......
  • Linux之资源管理器
    top命令用于实时的监控系统的处理器状态,以及其他硬件负载信息还有其他动态的进程信息等还可以按照排名,先后的显示某个进程CPU,内存的使用情况排名。top实际用法如下:1.进......
  • Linux中进程管理命令
    1.PS命令,用于报告当前系统的进程状态的命令ps-ef显示所有详细的进程信息-e列出程序时,显示每个程序所使用的环境变量-f显示UIDPID......
  • 一文梳理 | 电力企业网络安全管理及等级保护工作重点
    前言为加强电力行业网络安全监督管理,规范电力行业网络安全工作,国家能源局近日印发《电力行业网络安全管理办法》和《电力行业网络安全等级保护管理办法》(以下简称“两办法”......
  • 内网直播局域网直播校园直播系统方案,播控管理
    音视频融合应用系统​方案2022/11/03 目录第1章项目概况...11.1需求背景...11.2建设的必要性...11.3项目建设具备的基础条件...11.4建设内容...2第2章系统介......
  • 皕杰报表之性能管理
    1报表缓存当某个客户端访问某个报表,引擎将其计算出来后,会将运算结果缓存下来,之后如果再有别的客户端用相同的参数访问同一个报表,引擎会将缓存下来的报表结果直接返回给该客......
  • SQLServer2017管理工具的数据库还原操作
    原文链接:https://blog.csdn.net/qq_21209307/article/details/104992642还原数据库选择数据库点击右键选择还原数据库。在弹出的框内选择设备,点击输入框后面的“…”按钮,......
  • 大型三甲医院HIS系统源码 县乡一体医院管理系统源码 门诊住院医嘱药房药库发药管理系
    his系统源码,适用在县乡一体化,医联体分级诊疗项目上,​​本源码开发语言asp.net​​c#,数据库sqlserver2012,开发工具vs2015。技术框架mvc、ef等HIS英文全称hospitalinformat......
  • 默认管理员模式运行cmd
    一.本地安全策略1.1如果本地已经有本地安全策略,跳过此步1.2首先在任意地方创建一个.txt文件1.2.1内容如下:@echooffpushd"%~dp0"dir/bC:\Windows\servicing\P......
  • 管理经验
    10年时间把IT研发团队从10人扩大到600多人,有自己的努力,更多的是靠运气(平台和机遇)。为了让团队能变的更好,创造更多的价值,让员工更有成就感和归属感,我每天学习,努力提升自己......