目录
一. 标准库
像 fmt, os 这样具有常用功能的内置包. 列举一些如下:
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: 提供对字符型分片的操作。
index/suffixarray: 子字符串快速查询。
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:生成像 HTML 一样的数据与文本混合的数据驱动模板。
net-net/http-html:
net: 网络数据的基本操作。
http: 提供了一个可扩展的 HTTP 服务器和基础客户端,解析 HTTP 请求和回复。
html: HTML5 解析器。
runtime: Go 程序运行时的交互操作,例如垃圾回收和协程创建。
reflect: 实现通过程序运行时反射,让程序操作任意类型的变量。
1. regexp 包:正则表达式
用于正则表达式的匹配:
简单模式: 使用 match 方法
复杂模式: 先通过 Compile 方法将正则模式转为 Regexp 对象。然后我们使用该对象的匹配,查找,替换等函数。
func main() {
matched, err := regexp.Match(`foo.*`, []byte(`seafood`))
fmt.Println(matched, err)
matched, err = regexp.Match(`bar.*`, []byte(`seafood`))
fmt.Println(matched, err)
matched, err = regexp.Match(`a(b`, []byte(`seafood`))
fmt.Println(matched, err)
}
运行结果如下:
2. sync 包:锁和同步
用于线程间同步
2.1 sync.Mutex 互斥锁
它的作用是守护在临界区入口来确保同一时间只能有一个线程进入临界区。
2.2 sync.RWMutex 读写锁
他能通过 RLock() 来允许同一时间多个线程对变量进行读操作,但是只能一个线程进行写操作。如果使用 Lock() 将和普通的 Mutex 作用相同。
2.3 once.Do(call)
包中还有一个方便的 Once 类型变量的方法 , 这个方法确保被调用函数只能被调用一次。
func (o *Once) Do(f func())
map 类型是不存在锁的机制来实现这种效果(出于对性能的考虑),所以 map 类型是非线程安全的。当并行访问一个共享的 map 类型的数据,map 数据将会出错。
二. 包的使用
我们知道包是 Go 语言中代码组织和代码编译的主要方式。
1. 自定义包
当写自己包的时候,要使用短小的不含有 _
(下划线)的小写单词来为文件命名。
按照惯例,子目录和包之间有着密切的联系:为了区分,不同包存放在不同的目录下,每个包(所有属于这个包中的 go 文件)都存放在和包名相同的子目录下
2. 引用包
当我们要使用包里面的资源的时候,我们需要引入包.
import "包的路径或 URL 地址" 路径是指当前目录的相对路径
import "./pack1/pack1"
import "github.com/org1/pack1"
//这种方式导入的包, 可以直接使用 pack1 里面的资源, 而不用加 pack1.Func() 这样的前缀
import . "./pack1"
//这种导入方式, 可以帮助我们检查包 pack1, 只执行它的init函数并初始化其中的全局变量
import _ "./pack1/pack1"
3. 包的初始化
程序执行: 1.导入包 2.初始化 main 包 3.调用 main 函数
一个包可能有多个 init 函数甚至在一个源码文件中。init 函数是不能被调用的。
导入的包在包自身初始化前被初始化,而一个包在程序执行中只能初始化一次。