库源码文件:
不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用。
代码包声明的基本规则:
1. 同目录下的源码文件的代码包声明语句要一致。也就是说,它们要同属于一个代码包(package)。这对于所有源码文件都是适用的。
如果目录中有命令源码文件,那么其他种类的源码文件也应该声明属于main包。这也是能够成功构建运行它们的前提。
2. 源码文件声明的代码包的名称可以与其所在的目录的名称不同。在针对代码包进行构建时,生成的结果文件的主名称与其父目录的名称一致。
对于命令源码文件,构建生成可执行文件的主名称会与其父目录的名称相同。
面试题:
1. 如何拆分命令源码文件到其他代码包?
// demo5.go
package main import (
"36class/q5/lib"
"flag"
) var StudentName string func init() {
flag.StringVar(&StudentName, "name", "Default name", "Some description.")
} func main() {
flag.Parse()
lib5.Hello(StudentName)
}
在该命令源码文件中,增加了导入lib包,同时修改了main()函数。
再看下代码包文件:q5/lib/demo5_lib.go:
// demo5_lib.go
package lib5 import (
"fmt"
) func Hello(StudentName string) {
fmt.Printf("Hello, %s!\n", StudentName)
}
该文件中的函数Hello()首字母大写,表示可以被其他以外的包使用(public),否则只能在包内使用(private)。
要注意的是,该代码包的包名特意设为lib5,那么在demo5.go中引用Hello函数时,就需要使用包名lib5,而不是导入时指定的目录名lib。
2. 代码包的导入路径必须与其所在目录的相对路径保持一致吗?
代码包导入路径可以和包名不一致,在使用的时候需要使用包名。
先使用lib的相对路径,安装前面提供的代码包:
go install 36class/q5/lib
该命令执行成功后,会在当前过去(GoPath)的pkg目录下,生成相应的归档文件,如:
pkg/windows_amd64/36class/q5/lib.a
注意:源码文件所在的目录相对于GOPATH下src目录的相对路径,就是它代码包导入路径,而实际使用时给定的限定符(如上述文件中的“lib5.”)必须要与它声明所属的代码包名称一致。
要么把 :
package lib5
改为:
package lib
然后使用lib.Hello,如果保持lib5不变,那么就在调用限定符时使用“lib5.Hello”。
3. 什么样的程序实体才可以被当前包外的代码引用?
名称的首字母为大写的程序实体才可以被当前包外的代码引用,否则它就只能被当前包内的其他代码引用。
4. 对于程序实体,还可以使用怎样的访问权限规则?
通过创建internal代码包让一些程序实体仅仅能被当前模块中的其他代码引用。
这被称为 Go 程序实体的第三种访问权限:模块级私有。
具体规则是: internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。
当然,引用前需要先导入这个internal包。
对于其他代码包,导入该internal包都是非法的,无法通过编译。
思考题:
Q1: 如果需要导入两个代码包,而这两个代码包的导入路径的最后一级是相同的,比如:dep/lib/flag和flag,那么会产生冲突吗?
A1: 会报错redeclared。
Q2: 如果会产生冲突,那么怎样解决这种冲突,有几种方式?
可以通过包别名的方式解决冲突,如果导入的包不显式使用可以采用匿名的方式导入包。
本学习笔记是仅为了总结自己学到的Go语言核心知识,方便以后回忆,文中部分内容摘录自极客时间的《Go语言核心36讲》专栏,如有侵权,请联系我删除。