本节核心内容
- 介绍 Go语言中包的概念
- 介绍 Go语言中包的几种引入方法
- 介绍 Go语言中如何解决包引入的问题
本小节视频教程和代码:百度网盘
可先下载视频和源码到本地,边看视频边结合源码理解后续内容,边学边练。
包
包的概念和源文件
Go程序是通过把包链接到一起构成的。包是由一个个定义了属于该包的常量、类型、变量、函数(它们可以被同一个包内的所有文件访问,也可以通过导出而被其他的包使用)的源文件构成的。每个包的代码都可以作为很小的复用单元,被其他项目所引用。
每个源文件都有一个package语句定义了它属于哪个包,后面跟着可能为空的import集合声明了需要使用哪些包,再往后跟着可能为空的函数、类型、变量、常量的集合。
示例如下:
我们可以看到名为code和errno的文件的归属包,都为errno,这就表明,在Go中并不像Java那样以一个类作为复用单元,而是以包作为一个很小的复用单元。
总结:在Go中最小的单元是包,而包下的可以有多个源文件,源文件就相当于Java里的Class类,每个源文件通过package语句声明了该文件属于哪个包。
main包
在Go语言里,命名为main的包具有特殊的含义。Go语言的编译程序会试图把这种名字的包编译为二进制的可执行文件。所有用Go语言编译的可执行程序都必须有一个名为main的包。
当编译器发现这个某个包的名字为main是,它一定也会发现名为main()是函数,否则不会创建可执行文件。main()函数是程序的入口,所以,如果没有这个函数,程序就没有办法开始执行。程序编译时,会使用声明main包的代码所在的目录的目录名作为二进制可执行文件的文件名。
包目录的命名规范
所谓无规矩不成方圆,在开发Go语言之前,我们一定要了解Go语言的一些特性和规范才能更好的开发出高质量,可通用的代码,不然开发出一个只有你能看明白的程序,那只能算是自娱自乐罢了。
本节根据一些经典代码和公司开发习惯给出了一个命名规范示例,示例如下:
下面根据这个示例图,讲解一下我理解的开发规范:
conf: 本目录主要保存配置文件
handler:主要存放一些程序的入口文件,相当于Java中的Collter层
model:主要存放于数据库操作相关的文件
pkg:主要保存一些通用的工具类等代码
router:主要保存路由服务的代码
service:主要保存业务代码
vendor:主要保存项目本身的依赖包
conf.yaml:项目的配置文件,可放在跟目录下,也可放在conf文件夹下
main.go:程序的入口,一般放置在根目录下
导入
包的引入原理
程序的初始化和执行都起始于main包。如果main包还导入了其它的包,那么就会在编译时将它们依次导入。一个被多个地方导入的包只会被导入一次。当一个包被导入时,如果该包还导入了其它的包,那么会先将其它包导入进来,然后再对这些包中的包级常量和变量进行初始化,接着执行init函数(如果有的话),依次类推。等所有被导入的包都加载完毕了,就会开始对main包中的包级常量和变量进行初始化,然后执行main包中的init函数(如果存在的话),最后执行main函数。
包在导入时,查找依赖时根据从高到低的优先级来划分,大概:
- 当前包下的vendor目录。
- 向上级目录查找,直到找到src下的vendor目录。
- 在GOPATH下面查找依赖包。
- 在GOROOT目录下查找
包导入的语法
在写Go代码的时候经常用到import这个命令用来导入包文件,看到的方式参考如下:
1、常规导入
import(
"fmt"
)
然后在代码里面可以通过如下的方式调用
fmt.Println("hello world")
上面这个fmt是Go语言的标准库,他其实是去GOROOT下去加载该模块。
2、点操作
import (
. "fmt"
)
这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调用的fmt.Println(“hello world”) 可以省略的写成Println(“hello world”)。注意:该包内的函数不能与其重名。
示例:
3、别名操作
import( f “fmt” )
别名操作顾名思义可以把包命名成另一个用起来容易记忆的名字,别名操作调用包函数时前缀变成了重命名的前缀,即f.Println(“hello world”),通常为了解决导入多个重名包的问题。
示例:
4、_操作
import (
_ "github.com/go-sql-driver/mysql"
)
_操作其实只是引入该包但不使用,通常只为了执行该包中所有的init()函数,最常见的就是上面的mysql包。
如何解决导入的包报错的问题
当我们新接手一个Go语言的项目时,往往会遇到导入行代码报错的问题,如图:
图中的代码,在SPV-Client-Core处开始爆红,这种情况通常是表示在BSC目录中就没有这个文件夹,无法找到该依赖包从而报错,解决办法跟简单,没有依赖包,我们给它依赖包就是了,网上有很多的解决办法,通常是使用git get命令去获取所你需要的包,但这样往往会遇到一些你预料不到的问题,所以这种方式并不好用,而我的方式就很简单粗暴了。
直接去网上下载该依赖包,将其按照代码原来的路径放置依赖包,报错解决!。
小结
本小节讲解了Go语言中包的概念,以及包引入的几种方式,和开发中对于一些包引用的解决办法。
请发表评论