您现在的位置是:首页 >技术杂谈 >初识Go语言20-包与工程化【用go mod管理工程、包引入规则、init调用链、可见性】网站首页技术杂谈

初识Go语言20-包与工程化【用go mod管理工程、包引入规则、init调用链、可见性】

十一__一 2023-07-08 00:00:03
简介初识Go语言20-包与工程化【用go mod管理工程、包引入规则、init调用链、可见性】


包与工程化

用go mod管理工程

  初始化项目:

go mod init $module_name

$module_name和目录名可以不一样。上述命令会生成go.mod文件,该文件内容形如:

module go-course

go 1.17

require (
    github.com/ethereum/go-ethereum v1.10.8
    github.com/gin-gonic/gin v1.7.4
)

  Go依次从当前项目、GOROOT、GOPATH下寻找依赖包。

  1. 从当前go文件所在的目录逐级向上查找go.mod文件(假设go.mod位于目录mode_path下),里面定义了module_name,则引入包的路径为"module_name/包相对于mode_path的路径"。
  2. go标准库提供的包在GOROOT/src下。
  3. 第三方依赖包在GOPATH/pkg/mod下。

  从go1.7开始,go get只负责下载第三方依赖包,并把它加到go.mod文件里,由go install负责安装二进制文件。

  • go get github.com/mailru/easyjson会在GOPATH/pkg/mod目录下生成github.com/mailru/easyjson目录。
  • go install github.com/mailru/easyjson/easyjson会在GOPATH/bin下生成easyjson二进制可执行文件。

  go mod tidy通过扫描当前项目中的所有代码来添加未被记录的依赖至go.mod文件或从go.mod文件中删除不再被使用的依赖。

包引入规则

包的声明

  • go文件的第一行声明 package xxx。
  • 在包声明的上面可写关于包的注释,包注释也可以专门写在doc.go里。
  • 包名跟目录名可以不同。
  • 同一个目录下,所有go文件的包名必须一致。

包的引用

  • 可以直接使用同目录下其他go文件里的变量、函数、结构体。
  • 跨目录使用则需要变量前加入包名,并且引入包所在的目录。
imoprt "go-course/package"      //go-course是model名,package是目录名
mypackage.Add()     //mypackage是包名,它对应的目录是package
  • 在import块里可以引用父目录,也可以引用子目录。
  • 引用关系不能构成一个环。
  • 在import的目录前面可以给包起一个别名。
imoprt asd "go-course/package"
asd.Add()

init调用链

  main函数是go程序的唯一入口,所以main函数只能存在一个。main函数必须位于main包中。在main函数执行之前会先执行init()函数。在一个目录,甚至一个go文件里,init()可以重复定义。引入其他包时,相应包里的init()函数也会在main()函数之前被调用。

在这里插入图片描述

import _ "net/http/pprof"

  在目录前加一个_,代码里却没有显式地使用这个包里的函数或变量,实际上是想执行这个包里的init()函数。

可见性

  • 以小写字母开头命名的函数、变量、结构体只能在本包内访问。
  • 以大写字母开头命名的函数、变量、结构体在其他包中也可以访问。
  • 如果结构体名字以大写字母开头,而其成员变量、成员方法以小写字母开头,则这样的成员只能在本包内访问。

  Go中命名为internal的package,可以被平级目录和上一级目录所访问,更上层的目录不能访问。如下图c目录(internal的上一级目录)及其子孙目录之间可以任意import,但a目录和b目录不能import internal及其下属的所有目录。

在这里插入图片描述

在这里插入图片描述

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。