Merge pull request #181 from dake/master

校对13章
This commit is contained in:
Unknwon
2015-11-08 11:32:31 -05:00
6 changed files with 18 additions and 18 deletions

View File

@@ -9,7 +9,7 @@ type error interface {
```
错误值用来表示异常状态;我们可以在 5.2 节中看到它的标准用法。处理文件操作的例子可以在 12 章找到;我们将在 15 章看到网络操作的例子。errors 包中有一个 errorString 结构体实现了 error 接口。当程序处于错误状态时可以用 `os.Exit(1)` 来中止运行。
错误值用来表示异常状态;我们可以在 [5.2 节](05.2.md)中看到它的标准用法。处理文件操作的例子可以在 12 章找到;我们将在 15 章看到网络操作的例子。errors 包中有一个 errorString 结构体实现了 error 接口。当程序处于错误状态时可以用 `os.Exit(1)` 来中止运行。
## 13.1.1 定义错误
@@ -63,7 +63,7 @@ if f, err := Sqrt(-1); err != nil {
```
由于 `fmt.Printf` 会自动调用 `String()` 方法 (参见 10.7 节),所以错误信息 “Error: math - square root of negative number” 会打印出来。通常(错误信息)都会有像 “Error:” 这样的前缀,所以你的错误信息不要以大写字母开头。
由于 `fmt.Printf` 会自动调用 `String()` 方法 (参见 [10.7 节](10.7.md)),所以错误信息 “Error: math - square root of negative number” 会打印出来。通常(错误信息)都会有像 “Error:” 这样的前缀,所以你的错误信息不要以大写字母开头。
在大部分情况下自定义错误结构类型很有意义的,可以包含除了(低层级的)错误信息以外的其它有用信息,例如,正在进行的操作(打开文件等),全路径或名字。看下面例子中 os.Open 操作触发的 PathError 错误:
@@ -140,7 +140,7 @@ type Error interface {
```
在 15.1 节 我们可以看到怎么使用它。
[15.1 节](15.1.md) 我们可以看到怎么使用它。
正如你所看到的一样,所有的例子都遵循同一种命名规范:错误类型以 “Error” 结尾,错误变量以 “err” 或 “Err” 开头。

View File

@@ -2,7 +2,7 @@
正如名字一样这个recover内建函数被用于从 panic 或 错误场景中恢复:让程序可以从 panicking 重新获得控制权,停止终止过程进而恢复正常执行。
`recover` 只能在 defer 修饰的函数(参见 6.4 节)中使用:用于取得 panic 调用中传递过来的错误值,如果是正常执行,调用 `recover` 会返回 nil且没有其它效果。
`recover` 只能在 defer 修饰的函数(参见 [6.4 节](06.4.md))中使用:用于取得 panic 调用中传递过来的错误值,如果是正常执行,调用 `recover` 会返回 nil且没有其它效果。
<u>总结</u>panic 会导致栈被展开直到 defer 修饰的 recover() 被调用或者程序中止。
@@ -25,7 +25,7 @@ func protect(g func()) {
这跟 Java 和 .NET 这样的语言中的 catch 块类似。
log 包实现了简单的日志功能:默认的 log 对象向标准错误输出中写入并打印每条日志信息的日期和时间。除了 `Println``Printf` 函数,其它的致命性函数都会在写完日志信息后调用 os.Exit(1),那些退出函数也是如此。而 Panic 效果的函数会在写完日志信息后调用 panic可以在程序必须中止或发生了临界错误时使用它们就像当 web 服务器不能启动时那样(参见 15.4 节中的例子)。
log 包实现了简单的日志功能:默认的 log 对象向标准错误输出中写入并打印每条日志信息的日期和时间。除了 `Println``Printf` 函数,其它的致命性函数都会在写完日志信息后调用 os.Exit(1),那些退出函数也是如此。而 Panic 效果的函数会在写完日志信息后调用 panic可以在程序必须中止或发生了临界错误时使用它们就像当 web 服务器不能启动时那样(参见 [15.4 节](15.4.md)中的例子)。
log 包用那些方法methods定义了一个 Logger 接口类型,如果你想自定义日志系统的话可以参考(参见 [http://golang.org/pkg/log/#Logger](http://golang.org/pkg/log/#Logger))。

View File

@@ -31,7 +31,7 @@ fType1 = func f(a type1, b type2)
func check(err error) { if err != nil { panic(err) } }
```
2errorhandler这是一个包装函数。接收一个 fType1 类型的函数 fn 并返回一个调用 fn 的函数。里面就包含有 defer/recover 机制,这在 13.3 节中有相应描述。
2errorhandler这是一个包装函数。接收一个 fType1 类型的函数 fn 并返回一个调用 fn 的函数。里面就包含有 defer/recover 机制,这在 [13.3 节](13.3.md)中有相应描述。
```go
func errorHandler(fn fType1) fType1 {
@@ -47,7 +47,7 @@ func errorHandler(fn fType1) fType1 {
```
当错误发生时会 recover 并打印在日志中;除了简单的打印,应用也可以用 template 包(参见 15.7 节为用户生成自定义的输出。check() 函数会在所有的被调函数中调用,像这样:
当错误发生时会 recover 并打印在日志中;除了简单的打印,应用也可以用 template 包(参见 [15.7 节](15.7.md)为用户生成自定义的输出。check() 函数会在所有的被调函数中调用,像这样:
```go
func f1(a type1, b type2) {
@@ -65,7 +65,7 @@ func f1(a type1, b type2) {
通过这种机制,所有的错误都会被 recover并且调用函数后的错误检查代码也被简化为调用 check(err) 即可。在这种模式下,不同的错误处理必须对应不同的函数类型;它们(错误处理)可能被隐藏在错误处理包内部。可选的更加通用的方式是用一个空接口类型的切片作为参数和返回值。
我们会在 15.5 节的 web 应用中使用这种模式。
我们会在 [15.5 节](15.5.md)的 web 应用中使用这种模式。
<u>练习</u>
@@ -127,7 +127,7 @@ Returned normally from f.
**练习 13.3**[panic_defer_convint.go](exercises/chapter_13/panic_defer_convint.go)
写一个 ConvertInt64ToInt 函数把 int64 值转换为 int 值,如果发生错误(提示:参见 4.5.2.1 节)就 panic。然后在函数 IntFromInt64 中调用这个函数并 recover返回一个整数和一个错误。请测试这个函数
写一个 ConvertInt64ToInt 函数把 int64 值转换为 int 值,如果发生错误(提示:参见 [4.5.2.1 节](04.5.md#4521-整型-int-和浮点型-float))就 panic。然后在函数 IntFromInt64 中调用这个函数并 recover返回一个整数和一个错误。请测试这个函数
## 链接

View File

@@ -2,11 +2,11 @@
首先所有的包都应该有一定的必要文档,然后同样重要的是对包的测试。
在第 3 章中提到了 Go 的测试工具 gotest 我们已经在 9.8 节中使用过了。这里我们会用更多的例子进行详细说明。
在第 3 章中提到了 Go 的测试工具 gotest 我们已经在 [9.8 节](09.8.md)中使用过了。这里我们会用更多的例子进行详细说明。
名为 testing 的包被专门用来进行自动化测试,日志和错误报告。并且还包含一些基准测试函数的功能。
<u>备注:</u>gotest 是 Unix bash 脚本,所以在 Windows 下你需要配置 MINGW 环境(参见 2.5 节);在 Windows 环境下把所有的 pkg/linux_amd64 替换成 pkg/windows。
<u>备注:</u>gotest 是 Unix bash 脚本,所以在 Windows 下你需要配置 MINGW 环境(参见 [2.5 节](02.5.md));在 Windows 环境下把所有的 pkg/linux_amd64 替换成 pkg/windows。
对一个包做(单元)测试,需要写一些可以频繁(每次更新后)执行的小块测试单元来检查代码的正确性。于是我们必须写一些 Go 源文件来测试代码。测试程序必须属于被测试的包,并且文件名满足这种形式 `*_test.go`,所以测试代码和包中的业务代码是分开的。
@@ -69,7 +69,7 @@ func BenchmarkReverse(b *testing.B) {
命令 ```go test test.bench=.*``` 会运行所有的基准测试函数;代码中的函数会被调用 N 次N是非常大的数如 N = 1000000并展示 N 的值和函数执行的平均时间,单位为 ns纳秒ns/op。如果是用 testing.Benchmark 调用这些函数,直接运行程序即可。
具体可以参见 14.16 节中用 goroutines 运行基准测试的例子以及练习 13.3string_reverse_test.go
具体可以参见 [14.16 节](14.16.md)中用 goroutines 运行基准测试的例子以及练习 13.4[string_reverse_test.go](exercises/chapter_13/string_reverse_test.go)
## 链接

View File

@@ -1,10 +1,10 @@
# 13.8 测试的具体例子
在练习 11.2 中你写了一个叫 main_oddeven.go 的程序用来测试前 100 个整数是否是偶数。这个函数在包 even
在练习 9.4 中你写了一个叫 [main_oddeven.go](exercises/chapter_9/main_oddeven.go) 的程序用来测试前 100 个整数是否是偶数。这个函数属于 even
下面是一种可能的方案:
示例 13.7 [even_main.go](examples/chapter_13/even_main/even_main.go)
示例 13.7 [even_main.go](examples/chapter_13/even/even_main/even_main.go)
```go
package main
@@ -24,7 +24,7 @@ func main() {
上面使用了 even.go 中的 even 包:
示例 13.8 [even/even.go](examples/chapter_13/even/even.go)
示例 13.8 [even/even.go](examples/chapter_13/even/even/even.go)
```go
package even
@@ -41,7 +41,7 @@ func Odd(i int) bool { // Exported function
在 even 包的路径下,我们创建一个名为 oddeven_test.go 的测试程序:
示例 13.9 [even/oddeven_test.go](examples/chapter_13/even/oddeven_test.go)
示例 13.9 [even/oddeven_test.go](examples/chapter_13/even/even/oddeven_test.go)
```go
package even

View File

@@ -2,7 +2,7 @@
编写测试代码时,一个较好的办法是把测试的输入数据和期望的结果写在一起组成一个数据表:表中的每条记录都是一个含有输入和期望值的完整测试用例,有时还可以结合像测试名字这样的额外信息来让测试输出更多的信息。
实际测试时简单迭代表中的每条记录,并执行必要的测试。这在练习 13.4 中有具体的应用。
实际测试时简单迭代表中的每条记录,并执行必要的测试。这在练习 [13.4](exercises/chapter_13/string_reverse_test.go) 中有具体的应用。
可以抽象为下面的代码段:
@@ -29,7 +29,7 @@ func TestFunction(t *testing.T) {
```
如果大部分函数都可以写成这种形式,那么写一个帮助函数 verify 对实际测试会很有
如果大部分函数都可以写成这种形式,那么写一个帮助函数 verify 对实际测试会很有帮助
```go
func verify(t *testing.T, testnum int, testcase, input, output, expected string) {