GO语言学习笔记-包结构篇 Study for Go ! Chapter eight - Package Structure
持续更新 Go 语言学习进度中 ......
- GO语言学习笔记-类型篇 Study for Go! Chapter one - Type - slowlydance2me - 博客园 (cnblogs.com)
- GO语言学习笔记-表达式篇 Study for Go ! Chapter two - Expression - slowlydance2me - 博客园 (cnblogs.com)
- GO语言学习笔记-函数篇 Study for Go ! Chapter three - Function - slowlydance2me - 博客园 (cnblogs.com)
Study for Go ! Chapter eight - Package Structure
1. Workspace
工作空间主要由 src、bin、pkg 三个目录组成。通常需要将空间路径添加到 GOPATH 环境变量列表中,一遍相关工具能正常工作
在工作空间里,包括子包在内的所有源码文件都保存在 src 目录下。至于bin、pkg两个目录,其主要影响 go install/get 命令,它们会将编译结果 (可执行文件或静态库)安装到这两个目录下,以实现增量编译
环境变量
编译器等相关工具按 GOPATH 设置的路径搜索目标。也就是说在导入目标库时,排在列表前面的路径比当前工作空间优先级更高
另外,go get 默认将下载的第三方包保存到列表中第一个工作空间内
环境变量 GOROOT 用于指示工具链和标准库的存放位置。在生成工具链时,相关路径就已经嵌入到可执行文件内,故无须格外设置,但如果出现类似下面这样的错误提示,请检查路径是否一致
除通过设置 GOROOT 环境变量覆盖内部路径外,还可以移动目录 (改名、符号连接等),或重新编译工具链来解决
至于 GOBIN ,则是强制代替工作空间的 bin 目录,作为 go install 目标保存路径,这可避免将所有工作空间的 bin 路径 添加到 PATH 环境变量中
在使用 Git 等版本控制工具时,建议忽略 pkg、bin 目录。直接在 src, 或具体的子包下创建代码仓库 (repository)
2. 导入包
使用标准库或第三方包前,需使用 import 导入,参数是工作空间中以 src 为七十的绝对路径。编译器从标准库开始搜索,然后依次搜索 GOPATH 列表中的各个工作空间
除了使用默认包名外还可以使用别名,以解决同名冲突问题
Attention;
import 导入参数是路径,而非包名,尽管习惯将包和目录名保持一致,但这不是强制规定,在代码中引用包成员时,使用包名而非目录名
有四种导入方式
默认方式
别名方式
简便方式 (常用于单元测试代码中,不推荐在正式项目于代码中使用。)
初始化方式 (无法引用,仅用来初始化目标包,让目标包的初始化函数得以执行)
不能直接或者间接导入自己,不支持任何形式的循环导入
未使用的导入(不包含初始化方式)会被编译器视为错误
相对路径
除了工作空间和绝对路径外,部分工具还支持相对路径。可在非工作空间目录下,直接运行,编译一些测试代码
相对路径是指:当前目录,或以“ ./ ” 和 “ ../ ” 开头的路径
不管是否在 test 目录下,只要命令行路径正确,就可以用go build/run/test 进行编译,运行或测试。但因缺少工作空间相关目录,go install 会无法工作
在设置了 GOPATH 的工作空间中,相对路径会导致编译失败
go run 不受此影响,可正常执行
自定义路径
即便将代码托管在 GitHub ,但我们依然希望使用自有域名定义下载和导入路径。方法很简单,在 Web 服务器对应路径返回中包含 “ go-import ” 跳转信息即可
使用唯一的导入路径,方便日后迁移存储端,但此方法对 vendor 机制无效
3. 组织结构
包由一个或多个保存在同一目录下(不含子目录)的源码文件组成。包的用途类似名字空间(namespace),是成员作用域和访问权限的边界
包名和目录名并无关系,不要求保持一致
包名常用单数形式
源码文件必须使用 UTF-8 格式,否则会导致编译出错
同一目录下所有源码文件必须使用相同包名称,因导入是使用绝对路径,所以在搜索路径下,包必须有唯一路径,但无须是唯一名字
有几个被保留、有特殊含义的包名称;
main:可执行入口(入口函数 mian.mian)
all:标准库以及 GOPATH 中能找到的所有包
std,cmd:标准库及工具链
documentation:储存文档信息,无法导入(和目录名无关)
(相关工具忽略以” . “ 或 ” _ “ 开头的目录或文件,但是又允许导入保存在这些目录中的包! )
权限
所有成员在包内均可访问,无论是否在同一源码文件中。但只有名称首字母大写的为可导出成员,在包外可视 (该规则适用于全局变量、全局常量、类型、结构字段、函数、方法等)
可通过指针转换等方式绕开该限制
初始化
包内每个源码文件都可定义一到多个初始化函数,但编译器不保证执行次序。
实际上,所有这些初始化函数(包括标准库和导入的第三方包)都由编译器自动生成的一个包装函数进行调用,因此可保证在单一线程上执行,且只执行一次
编译器首先确保完成所有全局变量初始化,然后才开始执行初始化函数,知道这些全部结束后,运行时才正式进入 main.main 入口函数
可以在初始化函数中创建 goroutine,或等到它执行结束
如果在多个初始化函数中引用全局变量,那么最好在变量定义出直接赋值,因无法保证执行次序,所以任何初始化函数中的赋值都有可能“ 延迟无效 ”
延迟包
在进行代码重构时,我们会将一些内部模块陆续分离出来,以独立包形式维护。此时,基于首字母大小写的访问权限控制就显得过于粗犷。因为我们希望这些包导出成员仅在特定范围内访问,而不是向所有用户公开
内部包机制相当于增加了新的访问权限控制:所有保存在 internal 目录下的包 ( 包括自身 )仅能被其父目录下的包 ( 含所有层次的子目录 )访问
导入内部包必须使用完整路径
4. 依赖管理
如何管理和保存第三方包,一致存在争议。将项目所有的第三方依赖都放到一个独立工作空间中,可能会导致版本冲突。放到项目工作空间,又会把工作目录搞的面目全非。为此,引入了名为 vendor 的机制,专门存放第三方包,实现将源码和依赖完整打包分发
如果说 internal 针对内部,那么 vender 就是 针对外部 (external)
导入 vendor 中的第三方包,参数是以 vendor/ 为起点的绝对路径。这就避免了 vendor 目录位置带来的麻烦,让导入无论使用 vender,还是 GOPATH 都能保持一致
ATTENTION
vendor 比标准库优先级更高
question:当多个 vendor 目录嵌套时,如何正确查找目标 ?要知道引入的第三方包也可能存在有自己的 vendor 依赖目录
answer:从当前源文件所在目录开始,逐级向上构造 vendor 全路径,知道发现路径匹配的目标为止。匹配失败,则依旧搜索 GOPATH
要使用 vendor机制,须开启 ” GO15VENDOREXPERIMENT=1 “ 环境变量开关 ( GO 1.6 以上默认开启 )且必须是设置了 GOPATH 的工作空间
使用 go get 下载第三方包时,依旧使用 GOPATH 第一个工作空间,而非 vendor 目录。当前工具链中并没有真正意义上的包管理依赖,好在有不少的第三方工具可以选择
GO语言学习笔记-包结构篇 Study for Go ! Chapter eight - Package Structure的更多相关文章
- JVM学习笔记——内存结构篇
JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...
- GO语言学习笔记(一)
GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...
- Go语言学习笔记一: Hello World
Go语言学习笔记一: Hello World 听说Go语言又快又简单.即具有C语言的运行速度,又具有Python语言的开发效率,不知道真的假的.所以特意来学学这门"老"语言. 下载 ...
- Go语言学习笔记(1)——顺序编程
Go语言学习笔记这一堆主要是<Go语言编程>(人民邮电出版社)的读书笔记.中间会穿插一些零碎的点,比如源码学习之类的.大概就是这样吧. 1. 顺序编程 1.1 变量 变量的声明: var ...
- HTML语言学习笔记(会更新)
# HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...
- 2017-04-21周C语言学习笔记
C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...
- 2017-05-4-C语言学习笔记
C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...
- Haskell语言学习笔记(88)语言扩展(1)
ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...
- Go语言学习笔记十三: Map集合
Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...
- Go语言学习笔记十二: 范围(Range)
Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...
随机推荐
- MacOS如何使用语音输入
Siri是Apple旗下强大的语音助手,而Siri的语音输入是必不可少的的存在.目前的MacOS中都有语音听写功能,可以让它把我们的语音转化成为文字.如果你此时不想打字,或是不方便打字的情况下,这个功 ...
- NX环境变量设置脚本
1 @ECHO OFF 2 TITLE NX 环境变量设置 3 color 3f 4 :MENU 5 CLS 6 ECHO. NX环境变量设置工具 7 ECHO.******************* ...
- ULR1 B. 【ULR #1】光伏元件
一个n∗nn∗n的0101矩阵ai,jai,j,有些位置可以修改,代价为ci,jci,j.要求进行一些修改之后满足:设clicli为第ii行的11的个数,cricri为第ii列的11的个数,要求cli ...
- spring-nfjh
Spring Xml 文件报红第一时间检查set .get .构造方法 准备工作 JDK 最低版本17 设置Maven 见[王鹤老师的笔记] 本套Spring教程与其他Spring教程的区别可总结为以 ...
- 4、Redis底层原理(持久化+分布式锁)
Redis底层原理 持久化 Redis虽然是个内存数据库,但是Redis支持RDB和AOF两种持久化机制,将数据写往磁盘,可以有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即 ...
- c++学习5 预处理
一 内存分区 内存的分区变量存储,一般可以分为以下五个区,它们分别是: 可读可写 堆区:使用malloc.calloc.realloc.free以及c++里面的new和delete去动态申请. ...
- 执行Maven的test命令报错
参考网址:https://blog.csdn.net/weixin_46688566/article/details/126470742 解决方案 在pom.xml文件中加入以下依赖: <plu ...
- iOS学习十二之选择器控件UIPickerView
UIPickerView是一个简易的列表控件,用于提供有限个数的选项供用户选择. 它是通过代理和数据源的方法对其进行设置和数据源填充的,这种控件的设计模式也是代理模式的应用之一. 添加下面的代码即可实 ...
- sql 字符串末尾空格不占长度
print len('qwer ');--4 print len('qwer ');--4 print len('qwer ' + 't');-- ...
- grub-mkrescue:错误: `mformat` invocation failed
跟着兴业视频做操作系统的时候遇到了这个问题 解决方法: sudo apt-get install mtools 参考: (40条消息) vs code连接远程Ubuntu编写操作系统,grub-mkr ...