GO语言标准库概览

whitepanda 发布于2年前
0 条问题

Go标准库包含了大量包,提供了丰富广泛的功能特性。这里提供了概览仅仅是有选择性的且非常简单。本文发表后,标准库的内容还可能继续增加,因此 建议大家最好是通过在线查阅库API或使用godoc(包含在Go发布包中)来获取最新信息以及全面了解每个包所具备的功能。

 

exp包(试验性的)是那些未来可能被加入标准库的包起步的地方,因此除非你想参加这些包的开发(通过测试、讨论、提交补丁),否则不应该使用其 下面的包。exp包通常只存在于从Google Go源码树上签出的源码包中,但一般不会包含在预构建好的包中。其他包可以放心使用,虽然在写下本文的这一刻,很多包依旧不够完整。

 

Archive(归档)和Compression(压缩)包

Go支持读写tarball和.zip文件。与此相关的包为archive/tar和archive/zip;以及用于压缩tarball的 compress/gzip和compress/bzip2。

Go同样也支持其他压缩格式;例如用于TIFF图像和PDF文件的Lempel-Ziv-Welch (compress/lzw)格式。

 

Bytes(字节)和String(字符串)相关包

bytes和strings包中有很多相同的函数,但前者操作的是[]byte类型的值,而后者操作的是string类型的值。strings包 提供了所有最有用的功能函数,诸如查找子字符串、替换子字符串、拆分字符串、剔除字符串以及大小写变换等。strconv包提供了数字和布尔类型 与string类型相互转换的功能。

 

fmt包

提供了大量有用的print和scan函数,它们在本系列教程的第一和第二部分已有相关介绍。

 

unicode包

提供一些用于确定字符属性的函数,诸如判断一个字符是否是可打印的,或是否是一个数字。unicode/utf8与 unicode/utf16这两个包提供了rune(即,Unicode码点/字符)的编码和解码功能。

 

text/template和html/template包

可以被用于创建模板,这些模板可基于填入的数据生成文本形式的输出(例如HTML)。 这里是一个小且简单的有关text/template包使用的例子。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type GiniIndex  struct  {
     Country string
     Index float64
}
gini := []GiniIndex{{ "Japan" , 54.7}, { "China" , 55.0}, { "U.S.A." , 80.1}}
giniTable :=  template .New( "giniTable" )
giniTable.Parse(
'<TABLE>'  +
     '{{range .}}'  +
     '{{printf "<TR><TD>%s</TD><TD>%.1f%%</TD></TR>"'  +
     '.Country .Index}}' +
     '{{end}}'  +
     '</TABLE>' )
err := giniTable.Execute(os.Stdout, gini)

 

输出:

?
1
2
3
4
5
< TABLE >
< TR >< TD >Japan</ TD >< TD >54.7%</ TD ></ TR >
< TR >< TD >China</ TD >< TD >55.0%</ TD ></ TR >
< TR >< TD >U.S.A.</ TD >< TD >80.1%</ TD ></ TR >
</ TABLE >

 

template.New()函数用给定的名字创建了一个新的template.Template。模板名字用于识别模板,尤其是嵌入在其他模板 中时。template.Template.Parse()函数用于解析一个模板(通常从一个.html文件中),解析后模板即可用。 template.Template.Execute()函数执行这个模板,将结果输出到给定的io.Writer,并且从其第二个参数那里读取 用于生成模板的数据。在这个例子中,我将结果输出到os.Stdout,并将GiniIndex类型的gini切片作为数据传入(我将输出拆分为 多行以便让结果更加清晰)。

在模板内部,行为(action)包含在双大括号中({{和}})。{{range}} … {{end}}可用于迭代访问一个切片中的每个元素。这里我将切片中的每个GiniIndex设置为点(.);即是当前的元素。我们可以通过在名字访问导 出字段,当然名字前面需要用.来指明当前元素。{{printf}}的行为与fmt.Printf()函数类似,但用空格替换括号以及用于分隔参 数的逗号。

text/template和html/template包自身支持一种复杂的模板语言,包括许多action,迭代和条件分支,支持变量和方法 调用,以及其它一些。除此之外,html/templage包还对代码注入免疫。

 

集合包

切片是Go语言提供了最高效的集合类型,但有些时候使用一个更为特定的集合类型更有用或有必要。在多数情况下,内置的map类型已经足够了,但Go标准库还是提供了container包,其中包含了各种不同的集合包。


container/heap包

提供了操作heap(堆)的函数,这里heap必须是一个自定义类型的值,该类型必须满足定义在heap包中 heap.Interface。一个heap(严格地说是一个min-heap)按特定顺序维护其中的值 – 即第一个元素总是heap中最小的(对于max-heap,应该是最大的)- 这就是熟知的heap属性。heap.Interface中嵌入了sort.Interface以及Push()和Pop方法。

我们可以很容易地创建一个满足heap.Interface的自定义heap类型。下面是一个正在使用的heap的例子:

?
1
2
3
4
5
6
7
8
9
10
ints := &IntHeap{5, 1, 6, 7, 9, 8, 2, 4}
heap.Init(ints)  // Heapify
ints.Push(9)  // IntHeap.Push() doesn't preserve the heap property
ints.Push(7)
ints.Push(3)
heap.Init(ints)  // Must reheapify after heap-breaking changes
for  ints.Len() > 0 {
     fmt.Printf( "%v " , heap.Pop(ints))
}
fmt.Println()  // prints: 1 2 3 4 5 6 7 7 8 9 9

 

下面是完整的自定义heap实现。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
type IntHeap [] int
 
func (ints *IntHeap) Less(i, j  int bool  {
     return  (*ints)[i] < (*ints)[j]
}
 
func (ints *IntHeap) Swap(i, j  int ) {
     (*ints)[i], (*ints)[j] = (*ints)[j], (*ints)[i]
}
 
func (ints *IntHeap) Len()  int  {
     return  len(*ints)
}
 
func (ints *IntHeap) Pop() interface{} {
     x := (*ints)[ints.Len()-1]
     *ints = (*ints)[:ints.Len()-1]
     return  x
}
 
func (ints *IntHeap) Push(x interface{}) {
     *ints = append(*ints, x.( int ))
}

 

对于多数情况这个实现都足以应付了。我们可以将IntHeap类型换为type IntHeap struct { ints []int},这样代码更漂亮,我们可以在方法内部使用ints.ints,而不再是*ints了。

 

container/list包

提供了双向链表。元素以interface{}类型的值加入链表。从链表中获取的元素的类型为list.Element,其原始值可通过list.Element.Value访问到。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
items := list.New()
for  _, x := range strings.Split