“迭代”章节的练习
修改测试代码,以便调用者可以指定字符重复的次数,然后修复代码
首先按照“迭代”章节里面的步骤完成测试代码。得到最终结果:
为了使调用者可以指定字符重复的次数,毫无疑问就需要多添加一个参数来代表重复次数。
结果如下:
写一个 ExampleRepeat 来完善你的函数文档
在repeat_test.go文件里导入fmt库,并加入如下代码:
func ExampleRepeat() {
str := Repeat("a", 10)
fmt.Println(str)
//Output: aaaaaaaaaa
}
执行go test -v
得到如下结果:
看一下strings包。找到你认为可能有用的函数,并对它们编写一些测试。投入时间学习标准库会慢慢得到回报。
通过查阅文档,strings包里面的函数还是挺多的,这里对Contains、Index、Fields、Join四个函数。首先新建一个string_test.go文件,仿照之前的测试,完成代码:
package iteration
import "testing"
import "fmt"
import "strings"
func TestString(t *testing.T) {
test1 := strings.Contains("abcde", "bc")
expected1 := true
if test1 != expected1 {
t.Errorf("expected '%v' but got '%v'", expected1, test1)
}
test2 := strings.Index("abcde", "bc")
expected2 := 1
if test2 != expected2 {
t.Errorf("expected '%v' but got '%v'", expected2, test2)
}
}
func ExampleString() {
str1 := strings.Fields("a b c")
fmt.Println(str1)
str2 := strings.Join([]string{
"a","b","c"}," ")
fmt.Println(str2)
/*Output:
[a b c]
a b c*/
}
再次执行go test -v
得到如下结果:
归并排序TDD实践报告
先写测试
新建mergeSort_test.go文件,编写测试:
package iteration
import "testing"
func TestSort(t *testing.T) {
arr := []int{
5,6,1,3,9,7,4,2,8,10}
MergeSort(arr, 0, 10)
expected := [10]int{
1,2,3,4,5,6,7,8,9,10}
for i:=0;i<10;i++ {
if arr[i] != expected[i] {
t.Errorf("expected '%v' but got '%v'", expected[i], arr[i])
}
}
}
尝试运行测试
执行go test
指令。
先使用最少的代码来让失败的测试先跑起来
新建一个mergeSort.go文件,填入最简单的代码:
package iteration
func MergeSort(arr []int, l, r int) {
}
再次执行go test
指令,得到结果:
把代码补充完整,使得它能够通过测试
完善MergeSort函数,代码如下:
func MergeSort(arr []int, l, r int) {
if r==l+1 {
return
}
var mid int = (l+r)/2
MergeSort(arr, l, mid)
MergeSort(arr, mid, r)
arr_temp := [10]int{
0}
i, j, n := l, mid, 0
for i<mid && j<r {
if arr[i]<arr[j] {
arr_temp[n] = arr[i]
n++
i++
} else {
arr_temp[n] = arr[j]
n++
j++
}
}
for i<mid {
arr_temp[n] = arr[i]
n++
i++
}
for j<r {
arr_temp[n] = arr[j]
n++
j++
}
for i=0; i<n; i++ {
arr[l+i] = arr_temp[i]
}
}
再次执行go test
指令,即可通过测试:
重构
将原来的指针传递更改为值传递,这样就可以省去原来函数最后的那个迭代赋值步骤;同时可以给函数增加一个返回值,返回的就直接是相应的字符串。
先修改原来的测试代码:
func TestSort(t *testing.T) {
arr := MergeSort([10]int{
5,6,1,3,9,7,4,2,8,10}, 0, 10)
expected := [10]int{
1,2,3,4,5,6,7,8,9,10}
for i:=0;i<10;i++ {
if arr[i] != expected[i] {
t.Errorf("expected '%v' but got '%v'", expected[i], arr[i])
}
}
}
然后修改MergeSort函数:
func MergeSort(arr [10]int, l, r int) [10]int {
if r==l+1 {
return arr
}
var mid int = (l+r)/2
arr = MergeSort(arr, l, mid)
arr = MergeSort(arr, mid, r)
arr_temp := arr
i, j, n := l, mid, 0
for i<mid && j<r {
if arr[i]<arr[j] {
arr_temp[l+n] = arr[i]
n++
i++
} else {
arr_temp[l+n] = arr[j]
n++
j++
}
}
for i<mid {
arr_temp[l+n] = arr[i]
n++
i++
}
for j<r {
arr_temp[l+n] = arr[j]
n++
j++
}
return arr_temp
}
通过试验表明,参数是 []int 的话,就相当于是指针传递;而参数是 [10]int 的话,就相当于值传递。因而,在参数上跟原来的函数也有所不同。
执行go test
指令,仍然可以通过测试:
基准测试
在mergeSort_test.go文件里面加入测试代码:
func BenchmarkRepeat(b *testing.B) {
for i := 0; i < b.N; i++ {
MergeSort([10]int{
5,6,1,3,9,7,4,2,8,10}, 0, 10)
}
}
执行go test -bench=.
得到基准测试结果: