持续更新 Go 语言学习进度中 ......

  1. GO语言学习笔记-类型篇 Study for Go! Chapter one - Type - slowlydance2me - 博客园 (cnblogs.com)
  2. GO语言学习笔记-表达式篇 Study for Go ! Chapter two - Expression - slowlydance2me - 博客园 (cnblogs.com)
  3. 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的更多相关文章

  1. JVM学习笔记——内存结构篇

    JVM学习笔记--内存结构篇 在本系列内容中我们会对JVM做一个系统的学习,本片将会介绍JVM的内存结构部分 我们会分为以下几部分进行介绍: JVM整体介绍 程序计数器 虚拟机栈 本地方法栈 堆 方法 ...

  2. GO语言学习笔记(一)

    GO语言学习笔记 1.数组切片slice:可动态增长的数组 2.错误处理流程关键字:defer panic recover 3.变量的初始化:以下效果一样 `var a int = 10` `var ...

  3. Go语言学习笔记一: Hello World

    Go语言学习笔记一: Hello World 听说Go语言又快又简单.即具有C语言的运行速度,又具有Python语言的开发效率,不知道真的假的.所以特意来学学这门"老"语言. 下载 ...

  4. Go语言学习笔记(1)——顺序编程

    Go语言学习笔记这一堆主要是<Go语言编程>(人民邮电出版社)的读书笔记.中间会穿插一些零碎的点,比如源码学习之类的.大概就是这样吧. 1. 顺序编程 1.1 变量 变量的声明: var ...

  5. HTML语言学习笔记(会更新)

    # HTML语言学习笔记(会更新) 一个html文件是由一系列的元素和标签组成的. 标签: 1.<html></html> 表示该文件为超文本标记语言(HTML)编写的.成对出 ...

  6. 2017-04-21周C语言学习笔记

    C语言学习笔记:... --------------------------------- C语言学习笔记:学习程度的高低取决于.自学能力的高低.有的时候生活就是这样的.聪明的人有时候需要.用笨的方法 ...

  7. 2017-05-4-C语言学习笔记

    C语言学习笔记... ------------------------------------ Hello C语言:什么是程序:程序是指:完成某件事的既定方式和过程.计算机中的程序是指:为了让计算机执 ...

  8. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  9. Go语言学习笔记十三: Map集合

    Go语言学习笔记十三: Map集合 Map在每种语言中基本都有,Java中是属于集合类Map,其包括HashMap, TreeMap等.而Python语言直接就属于一种类型,写法上比Java还简单. ...

  10. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

随机推荐

  1. M1 安装homebrew详解

    1.打开终端创建安装目录 sudo mkdir -p /opt/homebrew 2.修改目录权限 sudo chown -R $(whoami) /opt/homebrew 3.进入opt文件夹 c ...

  2. Java基础——控制语句、switch结构与三元运算符

    package com.zhao.demo; public class Demo03 { public static void main(String[] args) { int num=1; swi ...

  3. Delphi中KeyPress、KeyUp、keydown事件区别

    KeyPress: 当用户按下键盘上的字符键(字母,数字) 会触发该事件,功能键则不会(F1-F12,Ctrl,Alt,Shift) KeyUp: 当按下键盘上的按键松开时,会触发OnKeyUp事件( ...

  4. redis分布式锁实现,setnx,nodejs版本

    const redis = require('ioredis'); const clienId = Math.random() * 100; //模拟客户端Id const lockKey = 'te ...

  5. 模态框拖拽案例分析--元素偏移量 offset 系列

    弹出框,我们也称为模态框. 模态框拖拽案例分析: (1)点击弹出层, 会弹出模态框, 并且显示灰色半透明的遮挡层. (2)点击关闭按钮,可以关闭模态框,并且同时关闭灰色半透明遮挡层. (3)鼠标放到模 ...

  6. Mac版SecureCRT修改配色方案

    SecureCRT是一个非常好用的远程连接工具,其可以配置特定关键词的颜色来使配置调试时更显目的辨别关键内容.网络上关于SecureCRT windows版本如何配置高亮配色的教程很多,但是关于Mac ...

  7. C# DataTable.Select()根据条件筛选数据

    1.前言: 很多时候我们获取到一个表的时候需要根据表的包含的队列去筛选内容,一般来说可能想到的就是遍历整个表的内容进行条件筛选,但是这种方式增加了代码量且易出错,DataTable.Select()就 ...

  8. mysql允许root用户在任何地方进行远程登录,并具有所有库任何操作权限

    在本机先使用root用户登录mysql: mysql -u root -p"youpass" 进行授权操作: mysql>GRANT ALL PRIVILEGES ON *. ...

  9. Encountered unexpected token: "ur" <K_ISOLATION>

    在用mybatis-plus的过程中 , 报如下错误 : Caused by: net.sf.jsqlparser.parser.ParseException: Encountered unexpec ...

  10. 昨天写了个ATM系统,学了点思想

    昨天上黑马的基础课终结,有个小测验是做个ATM系统 拿到之后我就明白该怎么做了 但是在后面遇到了瓶颈 就是 不知道怎么进入下级菜单 后面稍微看了一下他的做法,学会了 就继续做了,后面就做出来了 他这个 ...