《Go语言四十二章经》第七章 代码结构化
7.1 包的概念
Go语言使用包(package)的概念来组织管理代码,包是结构化代码的一种方式。和其他语言如JAVA类似,Go语言中包的主要作用是把功能相似或相关的代码组织在同一个包中,以方便查找和使用。在Go语言中,每个.go文件都必须归属于某一个包,每个文件都可有init()函数。包名在源文件中第一行通过关键字package指定,包名要小写。如下所示:
package fmt
每个目录下面可以有多个.go文件,这些文件只能属于同一个包,否则编译时会报错。同一个包下的不同.go文件相互之间可以直接引用变量和函数,所以这些文件中定义的全局变量和函数不能重名。
Go语言的可执行应用程序必须有main包,而且在main包中必须且只能有一个main()函数,main()函数是应用程序运行开始入口。在main包中也可以使用init()函数。
Go语言不强制要求包的名称和文件所在目录名称相同,但是这两者最好保持相同,否则很容易引起歧义。因为导入包的时候,会使用目录名作为包的路径,而在代码中使用时,却要使用包的名称。
7.2 包的导入
一个Go程序通过import关键字将一组包链接在一起。import其实 是导入目录,而不是定义的包名称,实际应用中我们一般都会保持一致。
例如标准包中定义的big包:package big,import "math/big" ,源代码其实是在GOROOT下src中的src/math/big目录。在代码中使用big.Int时,big指的才是.go文件中定义的包名称。
当导入多个包时,一般按照字母顺序排列包名称,像LiteIDE会在保存文件时自动完成这个动作。所谓导入包即等同于包含了这个包的所有的代码对象。
为避免名称冲突,同一包中所有对象的标识符必须要求唯一。但是相同的标识符可以在不同的包中使用,因为可以使用包名来区分它们。
import语句一般放在包名定义的下一行,导入包示例如下:
package main
import "context" //加载context包
导入多个包的常见的方式是:
import (
"fmt"
"net/http"
)
调用导入的包函数的一般方式:
fmt.Println("Hello World!")
下面介绍三种特殊的import方式。
点操作的含义是某个包导入之后,在调用这个包的函数时,可以省略前缀的包名,如这里可以写成Println("Hello World!"),而不是fmt.Println("Hello World!")。例如:
import( . "fmt" )
别名操作就是可以把包命名成另一个容易记忆的名字。例如:
import(
f "fmt"
)
别名操作调用包函数时,前缀变成了别名,即f.Println("Hello World!")。在实际项目中有时这样使用,但请谨慎使用,不要不加节制地采用这种形式。
_ 操作是引入某个包,但不直接使用包里的函数,而是调用该包里面的init函数,比如下面的mysql包的导入。此外在开发中,由于某种原因某个原来导入的包现在不再使用,也可以采用这种方式处理,比如下面fmt的包。代码示例如下:
import (
_ "fmt"
_ "github.com/go-sql-driver/mysql"
)
7.3 标准库
在 Go 的安装文件里包含了一些可以直接使用的标准库。在GOROOT/src中可以看到源码,也可以根据情况自行重新编译。
完整列表可以访问GoWalker(https://gowalker.org/)查看。
unsafe: 包含了一些打破 Go 语言“类型安全”的命令,一般的程序中不会被使用,可用在 C/C++ 程序的调用中。
syscall-os-os/exec:
os: 提供给我们一个平台无关性的操作系统功能接口,采用类UNIX设计,隐藏了不同操作系统间差异,让不同的文件系统和操作系统对象表现一致。
os/exec: 提供我们运行外部操作系统命令和程序的方式。
syscall: 底层的外部包,提供了操作系统底层调用的基本接口。
archive/tar 和 /zip-compress:压缩(解压缩)文件功能。
fmt-io-bufio-path/filepath-flag:
fmt: 提供了格式化输入输出功能。
io: 提供了基本输入输出功能,大多数是围绕系统功能的封装。
bufio: 缓冲输入输出功能的封装。
path/filepath: 用来操作在当前系统中的目标文件名路径。
flag: 对命令行参数的操作。
strings-strconv-unicode-regexp-bytes:
strings: 提供对字符串的操作。
strconv: 提供将字符串转换为基础类型的功能。
unicode: 为 unicode 型的字符串提供特殊的功能。
regexp: 正则表达式功能。
bytes: 提供对字符型分片的操作。
math-math/cmath-math/big-math/rand-sort:
math: 基本的数学函数。
math/cmath: 对复数的操作。
math/rand: 伪随机数生成。
sort: 为数组排序和自定义集合。
math/big: 大数的实现和计算。
container-/list-ring-heap: 实现对集合的操作。
list: 双链表。
ring: 环形链表。
time-log:
time: 日期和时间的基本操作。
log: 记录程序运行时产生的日志。
encoding/Json-encoding/xml-text/template:
encoding/Json: 读取并解码和写入并编码 Json 数据。
encoding/xml:简单的 XML1.0 解析器。
text/template: