回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,6 +1,6 @@
## 13.3. 示例: 深度相等判
## 13.3. 示例: 深度相等判
自reflect包的DeepEqual函可以對兩個值進行深度相等判。DeepEqual函使用建的==比操作符對基礎類型進行相等判斷,對於複合類型則遞歸該變量的每個基礎類型然後做類似的比較判斷。因它可以工作在任意的型上,甚至對於一些不支持==操作算符的型也可以工作,因此在一些測試代碼中廣泛地使用該函數。比如下面的代是用DeepEqual函數比較兩個字符串數組是否相等。
自reflect包的DeepEqual函可以对两个值进行深度相等判。DeepEqual函使用建的==比操作符对基础类型进行相等判断,对于复合类型则递归该变量的每个基础类型然后做类似的比较判断。因它可以工作在任意的型上,甚至对于一些不支持==操作算符的型也可以工作,因此在一些测试代码中广泛地使用该函数。比如下面的代是用DeepEqual函数比较两个字符串数组是否相等。
```Go
func TestSplit(t *testing.T) {
@@ -10,7 +10,7 @@ func TestSplit(t *testing.T) {
}
```
管DeepEqual函很方便,而且可以支持任意的數據類型,但是它也有不足之。例如,它將一個nil值的map和非nil值但是空的map作不相等,同nil值的slice 和非nil但是空的slice也作不相等。
管DeepEqual函很方便,而且可以支持任意的数据类型,但是它也有不足之。例如,它将一个nil值的map和非nil值但是空的map作不相等,同nil值的slice 和非nil但是空的slice也作不相等。
```Go
var a, b []string = nil, []string{}
@@ -20,7 +20,7 @@ var c, d map[string]int = nil, make(map[string]int)
fmt.Println(reflect.DeepEqual(c, d)) // "false"
```
希望在這里實現一個自己的Equal函,用於比較類型的值。和DeepEqual函數類似的地方是它也是基slice和map的每元素進行遞歸比較,不同之是它nil值的slicemap和非nil值但是空的slice作相等的值。基部分的比可以基reflect包完成和12.3章的Display函數的實現方法似。同,我也定了一個內部函equal於內部的遞歸比較。讀者目前不用心seen參數的具體含義。對於每一需要比的x和yequal函首先檢測它們是否都有效(或都效),然後檢測它們是否是相同的型。剩下的部分是一個鉅大的switch分支相同基礎類型的元素比。因爲頁面空的限,我省略了一些相似的分支。
希望在这里实现一个自己的Equal函,用于比较类型的值。和DeepEqual函数类似的地方是它也是基slice和map的每元素进行递归比较,不同之是它nil值的slicemap和非nil值但是空的slice作相等的值。基部分的比可以基reflect包完成和12.3章的Display函数的实现方法似。同,我也定了一个内部函equal于内部的递归比较。读者目前不用心seen参数的具体含义。对于每一需要比的x和yequal函首先检测它们是否都有效(或都效),然后检测它们是否是相同的型。剩下的部分是一个巨大的switch分支相同基础类型的元素比。因为页面空的限,我省略了一些相似的分支。
<u><i>gopl.io/ch13/equal</i></u>
```Go
@@ -63,7 +63,7 @@ func equal(x, y reflect.Value, seen map[comparison]bool) bool {
}
```
和前面的建議一樣,我們併不公reflect包相的接口,所以出的函需要在部自己將變量轉爲reflect.Value型。
和前面的建议一样,我们并不公reflect包相的接口,所以出的函需要在部自己将变量转为reflect.Value型。
```Go
// Equal reports whether x and y are deeply equal.
@@ -78,7 +78,7 @@ type comparison struct {
}
```
爲了確保算法對於有環的數據結構也能正常退出,我們必須記録每次已經比較的變量,而避免入第二次的比。Equal函分配了一組用於比較的結構體,包含每對比較對象的地址unsafe.Pointer形式保存型。我們要記録類型的原因是,有些不同的量可能對應相同的地址。例如如果x和y都是數組類型,那x和x[0]將對應相同的地址y和y[0]也是對應相同的地址,可以用於區分xy之的比或x[0]y[0]之的比是否進行過了。
为了确保算法对于有环的数据结构也能正常退出,我们必须记录每次已经比较的变量,而避免入第二次的比。Equal函分配了一组用于比较的结构体,包含每对比较对象的地址unsafe.Pointer形式保存型。我们要记录类型的原因是,有些不同的量可能对应相同的地址。例如如果x和y都是数组类型,那x和x[0]将对应相同的地址y和y[0]也是对应相同的地址,可以用于区分xy之的比或x[0]y[0]之的比是否进行过了。
```Go
// cycle check
@@ -96,7 +96,7 @@ if x.CanAddr() && y.CanAddr() {
}
```
是Equal函用法的例子:
是Equal函用法的例子:
```Go
fmt.Println(Equal([]int{1, 2, 3}, []int{1, 2, 3})) // "true"
@@ -105,7 +105,7 @@ fmt.Println(Equal([]string(nil), []string{})) // "true"
fmt.Println(Equal(map[string]int(nil), map[string]int{})) // "true"
```
Equal函甚至可以處理類似12.3章中致Display陷入陷入死循環的帶有環的數據
Equal函甚至可以处理类似12.3章中致Display陷入陷入死循环的带有环的数据
```Go
// Circular linked lists a -> b -> a and c -> c.
@@ -122,6 +122,6 @@ fmt.Println(Equal(a, b)) // "false"
fmt.Println(Equal(a, c)) // "false"
```
**練習 13.1**義一個深比較函數,對於十億以內的數字比,忽略型差
**练习 13.1**义一个深比较函数,对于十亿以内的数字比,忽略型差
**練習 13.2** 編寫一個函數,報告其參數是否循環數據結構
**练习 13.2** 编写一个函数,报告其参数是否循环数据结构