Go语言学习笔记 -- 包

包的定义

包是函数和数据的集合,使用pacakge关键字开始包的定义。文件名不需要与包名一致,包名使用小写字母。包可以由多个文件组成,但是每个文件都要使用相同的package <name>这一行,name为包的名字。

例如我们在文件even.go中,使用包名even定义一个包。

package even                    <--开始定义包

func Even(i int) bool {         <--导出的函数
    return i%2 == 0
}

func odd(i int) bool {          <--私有函数
    return i%2 == 1
}

以大写字母开头的名字是可以导出的,可以在包的外部访问。小写字母开头的名字为私有的,只能在包内部访问。

现在构建这个包,在$GOPATH下新建一个目录,将even.go拷贝到目录下

$ mkdir $GOPATH/src/even
$ cp even.go $GOPATH/src/even/
$ go build
$ go install even

构建完成后就可以在myeven.go代码里引用这个包:

package main

import (
    "even"    <--导入even包
    "fmt"
)

func main(){
    fmt.Printf("2 is even : %v\n", even.Even(2));  <--调用even包中的函数
}

调用某个包中函数的写法是<packagename>.Function()

在 Go 中,当函数的首字母大写的时候,函数会被从包中导出(在包外部可见,或者说公有的),因此函数名是 Even 。如果修改 myeven.go 的第 10 行,使用未导出的函数even.odd :
fmt.Printf(“Is %d even? %v\n”, i, even.odd(i))
由于使用了 私有 的函数,会得到一个编译错误:
myeven.go:10: cannot refer to unexported name even.odd
概括来说:
• 公有函数的名字以 大写 字母开头;
• 私有函数的名字以 小写 字母开头。

测试包

在 Go 中为包编写单元测试应当是一种习惯。编写测试需要包含 testing 包和程序 go test 。两者都有良好的文档。

go test 程序调用了所有的测试函数。even 包没有定义任何测试函数,执行 go test ,这样:

$ go test
?         even [no test files]

在 测 试 文 件 中 定 义 一 个 测 试 来 修 复 这 个。 测 试 文 件 也 在 包 目 录 中, 被 命 名 为*_test.go 。 这些测试文件同 Go 程序中的其他文件一样, 但是 go test 只会执行测试函数。每个测试函数都有相同的标识,它的名字以 Test 开头:
func TestXxx(t *testing.T)
编写测试时,需要告诉 go test 测试是失败还是成功。测试成功则直接返回。当测试失败可以用下面的函数标记 。这是非常重要的(参阅 go doc testing 或 go help testfunc 了解更多):

func (t *T) Fail()
Fail 标记测试函数失败,但仍然继续执行。
func (t *T) FailNow()
FailNow 标记测试函数失败,并且中断其执行。当前文件中的其余的测试将被跳过,然后执行下一个文件中的测试。
func (t *T) Log(args … i n t e r f a c e { } )
Log 用默认格式对其参数进行格式化,与 Print() 类似,并且记录文本到错误日志。
func (t *T) Fatal(args … i n t e r f a c e { } )
Fatal 等价于 Log() 后跟随 FailNow() 。

将这些凑到一起,就可以编写测试了。首先,选择名字 even_test.go 。然后添加下面的内容:

Listing 3.3. even 包的测试
package even 
import "testing" 
func TestEven(t *testing.T) { 
    if ! Even(2) {
        t.Log("2 should be even ! ")
        t.Fail()
    }
}

注意在第一行使用了 package even ,测试使用与被测试的包使用相同的名字空间。这不仅仅是为了方便,也允许了测试未导出的函数和结构。然后导入 testing 包,并且在第 5 行定义了这个文件中唯一的测试函数。展示的 Go 代码应当没有任何惊异的地方,检查了 Even 函数是否工作正常。现在等待了好久的时刻到了,执行测试:

% go test
ok  even 0.001s

测试执行并且报告 ok 。成功了!
如果重新定义测试函数,就可以看到一个失败的测试:

// Entering the twilight zone
func TestEven(t *testing.T) {
    if Even(2) {
        t.Log("2 should be odd ! ")
        t.Fail()
    }
}

然后得到:

$ go test even
--- FAIL: TestEven (0.00s)
    even_test.go:8: 2 should be Even!
FAIL
FAIL    even    0.002s

然后你可以以此行事(修复测试的实例)

!!!! 在编写包的时候应当一边写代码,一边写(一些)文档和测试函数。这可以让你的程序更好,并且它展示了你的努力。

The Go test suite also allows you to incorperate example functions which serve as documentation and as tests. These functions need to start with Example .

func ExampleEven() {
    if Even(2) {
        fmt.Printf("Is Even\n")
    }
    //Output:
    //Is Even
}

Those last two comments lines are part of the example, go test uses those to check the generated output with the text in the comments. If there is a mismatch the test fails.

常用的包

fmt

包 fmt 实现了格式化的 I/O 函数,这与 C 的 printf 和 scanf 类似。格式化短语派生于 C 。一些短语(%-序列)这样使用:
%v
默认格式的值。当打印结构时,加号(%+v)会增加字段名;
%#v
Go 样式的值表达;
%T
带有类型的 Go 样式的值表达;

io

这个包提供了原始的 I/O 操作界面。它主要的任务是对 os 包这样的原始的 I/O 进行封装,增加一些其他相关,使其具有抽象功能用在公共的接口上。

bufio

这个包实现了缓冲的 I/O。它封装于 io.Reader 和 io.Writer 对象,创建了另一个对象(Reader 和 Writer)在提供缓冲的同时实现了一些文本 I/O 的功能。

sort

sort 包提供了对数组和用户定义集合的原始的排序功能。

strconv

strconv 包提供了将字符串转换成基本数据类型,或者从基本数据类型转换为字符串的功能。

os

os 包提供了与平台无关的操作系统功能接口。其设计是 Unix 形式的。

sync

sync 包提供了基本的同步原语,例如互斥锁。

flag

flag 包实现了命令行解析。

encoding/json

encoding/json 包实现了编码与解码 RFC 4627 [2] 定义的 JSON 对象。

html/template

数据驱动的模板,用于生成文本输出,例如 HTML。将模板关联到某个数据结构上进行解析。模板内容指向数据结构的元素(通常结构的字段或者 map 的键)控制解析并且决定某个值会被显示。模板扫描结构以便解析,而 “游标” @ 决定了当前位置在结构中的值。

net/http

net/http 实现了 HTTP 请求、响应和 URL 的解析,并且提供了可扩展的 HTTP 服务和基本的 HTTP 客户端。

unsafe

unsafe 包包含了 Go 程序中数据类型上所有不安全的操作。 通常无须使用这个。

reflect

reflect 包实现了运行时反射,允许程序通过抽象类型操作对象。通常用于处理静态类型 interface{} 的值,并且通过 Typeof 解析出其动态类型信息,通常会返回一个有接口类型 Type 的对象。

os/exec

os/exec 包执行外部命令。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值