This commit is contained in:
Xargin 2016-08-03 16:27:12 +08:00
parent caa6653b3d
commit ea4d66c603
4 changed files with 6 additions and 6 deletions

View File

@ -1,7 +1,7 @@
## 11.1. go test ## 11.1. go test
go test命令是一个按照一定的约定和组织的测试代码的驱动程序。在包目录内所有以_test.go为后缀名的源文件并不是go build构建包的一部分它们是go test测试的一部分。 go test命令是一个按照一定的约定和组织来测试代码的程序。在包目录内,所有以`_test.go`为后缀名的源文件在执行go build时不会被构建成包的一部分它们是go test测试的一部分。
\*_test.go文件中有三种类型的函数测试函数、基准测试函数、示例函数。一个测试函数是以Test为函数名前缀的函数用于测试程序的一些逻辑行为是否正确go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。基准测试函数是以Benchmark为函数名前缀的函数它们用于衡量一些函数的性能go test命令会多次运行基准函数以计算一个平均的执行时间。示例函数是以Example为函数名前缀的函数提供一个由编译器保证正确性的示例文档。我们将在11.2节讨论测试函数的所有细节,在11.4节讨论基准测试函数的细节然后在11.6节讨论示例函数的细节。 `*_test.go`文件中,有三种类型的函数:测试函数、基准测试(benchmark)函数、示例函数。一个测试函数是以Test为函数名前缀的函数用于测试程序的一些逻辑行为是否正确go test命令会调用这些测试函数并报告测试结果是PASS或FAIL。基准测试函数是以Benchmark为函数名前缀的函数它们用于衡量一些函数的性能go test命令会多次运行基准函数以计算一个平均的执行时间。示例函数是以Example为函数名前缀的函数提供一个由编译器保证正确性的示例文档。我们将在11.2节讨论测试函数的所有细节,在11.4节讨论基准测试函数的细节然后在11.6节讨论示例函数的细节。
go test命令会遍历所有的\*_test.go文件中符合上述命名规则的函数然后生成一个临时的main包用于调用相应的测试函数然后构建并运行、报告测试结果,最后清理测试中生成的临时文件。 go test命令会遍历所有的`*_test.go`文件中符合上述命名规则的函数生成一个临时的main包用于调用相应的测试函数接着构建并运行、报告测试结果,最后清理测试中生成的临时文件。

View File

@ -16,7 +16,7 @@ func writeHeader(w io.Writer, contentType string) error {
因为Write方法需要传入一个byte切片而我们希望写入的值是一个字符串所以我们需要使用[]byte(...)进行转换。这个转换分配内存并且做一个拷贝但是这个拷贝在转换后几乎立马就被丢弃掉。让我们假装这是一个web服务器的核心部分并且我们的性能分析表示这个内存分配使服务器的速度变慢。这里我们可以避免掉内存分配么 因为Write方法需要传入一个byte切片而我们希望写入的值是一个字符串所以我们需要使用[]byte(...)进行转换。这个转换分配内存并且做一个拷贝但是这个拷贝在转换后几乎立马就被丢弃掉。让我们假装这是一个web服务器的核心部分并且我们的性能分析表示这个内存分配使服务器的速度变慢。这里我们可以避免掉内存分配么
这个io.Writer接口告诉我们关于w持有的具体类型的唯一东西就是可以向它写入字节切片。如果我们回顾net/http包中的内幕我们知道在这个程序中的w变量持有的动态类型也有一个允许字符串高效写入的WriteString方法这个方法会避免去分配一个时的拷贝。这可能像在黑夜中射击一样但是许多满足io.Writer接口的重要类型同时也有WriteString方法包括\*bytes.Buffer\*os.File和\*bufio.Writer。 这个io.Writer接口告诉我们关于w持有的具体类型的唯一东西就是可以向它写入字节切片。如果我们回顾net/http包中的内幕我们知道在这个程序中的w变量持有的动态类型也有一个允许字符串高效写入的WriteString方法这个方法会避免去分配一个时的拷贝。这可能像在黑夜中射击一样但是许多满足io.Writer接口的重要类型同时也有WriteString方法包括\*bytes.Buffer\*os.File和\*bufio.Writer。
我们不能对任意io.Writer类型的变量w假设它也拥有WriteString方法。但是我们可以定义一个只有这个方法的新接口并且使用类型断言来检测是否w的动态类型满足这个新接口。 我们不能对任意io.Writer类型的变量w假设它也拥有WriteString方法。但是我们可以定义一个只有这个方法的新接口并且使用类型断言来检测是否w的动态类型满足这个新接口。

View File

@ -1,6 +1,6 @@
## 7.13. 类型开关 ## 7.13. 类型开关
接口被以两种不同的方式使用。在第一个方式中以io.Readerio.Writerfmt.Stringersort.Interfacehttp.Handler和error为典型一个接口的方法表达了实现这个接口的具体类型间的相性,但是隐藏了代表的细节和这些具体类型本身的操作。重点在于方法上,而不是具体的类型上。 接口被以两种不同的方式使用。在第一个方式中以io.Readerio.Writerfmt.Stringersort.Interfacehttp.Handler和error为典型一个接口的方法表达了实现这个接口的具体类型间的相性,但是隐藏了代表的细节和这些具体类型本身的操作。重点在于方法上,而不是具体的类型上。
第二个方式利用一个接口值可以持有各种具体类型值的能力并且将这个接口认为是这些类型的union联合。类型断言用来动态地区别这些类型并且对每一种情况都不一样。在这个方式中重点在于具体的类型满足这个接口而不是在于接口的方法如果它确实有一些的话并且没有任何的信息隐藏。我们将以这种方式使用的接口描述为discriminated unions可辨识联合 第二个方式利用一个接口值可以持有各种具体类型值的能力并且将这个接口认为是这些类型的union联合。类型断言用来动态地区别这些类型并且对每一种情况都不一样。在这个方式中重点在于具体的类型满足这个接口而不是在于接口的方法如果它确实有一些的话并且没有任何的信息隐藏。我们将以这种方式使用的接口描述为discriminated unions可辨识联合

View File

@ -6,4 +6,4 @@
因为在Go语言中只有当两个或更多的类型实现一个接口时才使用接口它们必定会从任意特定的实现细节中抽象出来。结果就是有更少和更简单方法经常和io.Writer或 fmt.Stringer一样只有一个的更小的接口。当新的类型出现时小的接口更容易满足。对于接口设计的一个好的标准就是 ask only for what you need只考虑你需要的东西 因为在Go语言中只有当两个或更多的类型实现一个接口时才使用接口它们必定会从任意特定的实现细节中抽象出来。结果就是有更少和更简单方法经常和io.Writer或 fmt.Stringer一样只有一个的更小的接口。当新的类型出现时小的接口更容易满足。对于接口设计的一个好的标准就是 ask only for what you need只考虑你需要的东西
我们完成了对methods和接口的学习过程。Go语言良好的支持面向对象风格的编程不是说你仅仅只能使用它。不是任何事物都需要被当做成一个对象独立的函数有它们自己的用处未封装的数据类型也是这样。同时观察到这两个在本书的前五章的例子中没有调用超过两打方法像input.Scan与之相反的是普遍的函数调用如fmt.Printf。 我们完成了对methods和接口的学习过程。Go语言良好的支持面向对象风格的编程不是说你仅仅只能使用它。不是任何事物都需要被当做成一个对象独立的函数有它们自己的用处未封装的数据类型也是这样。同时观察到这两个在本书的前五章的例子中没有调用超过两打方法像input.Scan与之相反的是普遍的函数调用如fmt.Printf。