库源码文件不能被直接运行,它仅用于存放程序实体。只要遵从 Go 语言规范,这些程序实体就可以被其他代码使用。
首发地址:库源码文件
核心知识
- 代码包声明
- 代码包引用
- 模块级私有internal
程序实体是什么?
在 Go 语言中,它是变量、常量、函数、结构体和接口的统称。
代码包声明的基本规则
- 第一条规则,同目录下的源码文件的代码包声明语句要一致。也就是说,它们要同属于一个代码包。这对于所有源码文件都是适用的。
- 第二条规则,源码文件声明的代码包的名称可以与其所在的目录的名称不同。在针对代码包进行构建时,生成的结果文件的主名称与其父目录的名称一致。
什么样的程序实体才可以被当前包外的代码引用?
名称的首字母为大写的程序实体才可以被当前包外的代码引用,否则它就只能被当前包内的其他代码引用。
对于程序实体,还可以使用怎样的访问权限规则?
通过创建internal代码包让一些程序实体仅仅能被当前模块中的其他代码引用。
这被称为 Go 程序实体的第三种访问权限:模块级私有。
具体规则是,internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。
当然,引用前需要先导入这个interna包。
对于其他代码包,导入该interna包都是非法的,无法通过编译。
额外知识
如果需要导入两个代码包,而这两个代码包的导入路径的最后一级是相同的,比如:dep/lib/flag和flag,那么会产生冲突吗?
import后路径最后一级相同,不一定会冲突。
分为两种情况:
- 如果文件夹下文件声明的包名相同,则肯定冲突,会报错redeclared。
- 如果文件夹下文件声明的包名不同,也不会冲突。
如果会产生冲突,那么怎样解决这种冲突,有几种方式?
- 给包设置别名,调用的时候来区分开不同的package,比如:import(b “bbbb”)
- 导入的点操作,import(. “bbbb”)。这样就可以直接调用bbbb下面的函数而不用再bbbb.funcname的方式调用。
- 如果只是想引入某包并没有在代码中实际调用则可以这么处理来避免冲突:import(_ “bbbb”)
- 像第一问一样采取不同的包名声明,毕竟包名不一定要和文件夹名一样
小结
- 同一个文件夹下,包的声明语句需要相同,代表同一个包。
- 包名不需要和其所在的文件夹名相同。
- 首字母大小写来代表可见性,大写public/小写private
- 使用internal代码包模块级私有