golang语言 包、模块

go语言101,对引用路径作了比较详细的解释

一个代码包可以由若干Go源文件组成。一个代码包的源文件须都处于同一个目录下。 一个目录(不包含子目录)下的所有源文件必须都处于同一个代码包中,亦即这些源文件开头的package pkgname语句必须一致。 所以,一个代码包对应着一个目录(不包含子目录),反之亦然。 对应着一个代码包的目录称为此代码包的目录。 一个代码包目录下的每个子目录对应的都是另外一个独立的代码包。

对于官方Go SDK来说,一个引入路径中包含有internal目录名的代码包被视为一个特殊的代码包。 它只能被此internal目录的直接父目录中的代码包所引入。 比如,代码包.../a/b/c/internal/d/e/f.../a/b/c/internal只能被引入路径含有.../a/b/c前缀的代码包引入。

根据不同的情形,名称为vendor的目录也可能被视为特殊的代码包目录。下面的段落将会解释哪些vendor目录将被视为特殊的目录。

Go SDK 1.11版本引入了模块(modules)特性的概念。 一个模块可以被看做是一些拥有一个共同的根目录的代码包集合,即一个代码包树。 每个模块关联着一个根引入路径和一个语义化版本号 语义化版本号的主版本须体现在根引入路径中,除了v0v1主版本号。 两个关联着不同的根引入路径的模块被视为两个不同的模块。

包不能循环依赖,模块可以循环依赖

包的名称和目录一般是相同的,引入的是包的目录,使用的是包的名称 待验证

一个包可能包含多个init()函数,他们的执行顺序不确定,init()不能被显式调用,init()在变量初始化完成后被调用,串行执行,只被执行一遍

go的构建工具将.go文件按文件名排序,然后依次调用编译器编译。

导入的包会在当前包之前被初始化,多次导入相同的包,该包只会初始化一次

一个约定就是包名应为其源码目录的基本名称。在 src/pkg/encoding/base64 中的包应作为 "encoding/base64" 导入,其包名应为 base64, 而非 encoding_base64 或 encodingBase64。

 p 导入了包 q,则 q 的 init 函数会在 p 的任何函数启动前完成。

函数 main.main 会在所有的 init 函数结束后启动。

一个程序中所涉及到的所有的在运行时刻要用到的代码包的加载是串行执行的。 在一个程序启动时,每个包中总是在它所有依赖的包都加载完成之后才开始加载。 程序代码包总是最后一个被加载的代码包。每个被用到的包会被而且仅会被加载一次。

在加载一个代码包的过程中,所有的声明在此包中的init函数将被串行调用并且仅调用执行一次。 一个代码包中声明的init函数的调用肯定晚于此代码包所依赖的代码包中声明的init函数。 所有的init函数都将在调用main入口函数之前被调用执行。

在同一个源文件中声明的init函数将按从上到下的顺序被调用执行。 对于声明在同一个包中的两个不同源文件中的两个init函数,Go语言白皮书推荐(但不强求)按照它们所处于的源文件的名称的词典序列(对英文来说,即字母顺序)来调用。 所以最好不要让声明在同一个包中的两个不同源文件中的两个init函数存在依赖关系。

在加载一个代码包的时候,此代码包中声明的所有包级变量都将在此包中的任何一个init函数执行之前初始化完毕。

导入的包可以以空行进行分组,gofmt和goimports等工具,可以把组内的包独立排序

import mrand "math/rand" // 重命名,在当前文件里有效

import _ "math/rand" // 匿名导入

import . "fmt" // 可以直接使用 Printf(...)

猜你喜欢

转载自www.cnblogs.com/ts65214/p/12976419.html