This commit is contained in:
chai2010
2016-01-18 11:14:19 +08:00
parent a91355f5f1
commit 884ada9cd0
20 changed files with 116 additions and 92 deletions

View File

@@ -87,4 +87,4 @@ fmt.Println(geometry.PathDistance(perim)) // "12", standalone function
fmt.Println(perim.Distance()) // "12", method of geometry.Path
```
譯註:如果我們要用方法去計算perim的distance還需要去寫全geometry的包名和其函數名但是因爲Path這個變量定義了一個可以直接用的Distance方法所以我們可以直接寫perim.Distance()。相當於可以少打很多字作者應該是這個意思。因爲在Go里包外調用函數需要帶上包名還是挺麻煩的。
**譯註:** 如果我們要用方法去計算perim的distance還需要去寫全geometry的包名和其函數名但是因爲Path這個變量定義了一個可以直接用的Distance方法所以我們可以直接寫perim.Distance()。相當於可以少打很多字作者應該是這個意思。因爲在Go里包外調用函數需要帶上包名還是挺麻煩的。

View File

@@ -63,4 +63,4 @@ m.Add("item", "3") // panic: assignment to entry in nil map
對Get的最後一次調用中nil接收器的行爲卽是一個空map的行爲。我們可以等價地將這個操作寫成Value(nil).Get("item")但是如果你直接寫nil.Get("item")的話是無法通過編譯的因爲nil的字面量編譯器無法判斷其準備類型。所以相比之下最後的那行m.Add的調用就會産生一個panic因爲他嚐試更新一個空map。
由於url.Values是一個map類型併且間接引用了其key/value對因此url.Values.Add對這個map里的元素做任何的更新、刪除操作對調用方都是可見的。實際上就像在普通函數中一樣雖然可以通過引用來操作內部值但在方法想要脩改引用本身是不會影響原始值的比如把他置爲nil或者讓這個引用指向了其它的對象調用方都不會受影響。(譯註因爲傳入的是存儲了內存地址的變量你改變這個變量是影響不了原始的變量的想想C語言是差不多的)
由於url.Values是一個map類型併且間接引用了其key/value對因此url.Values.Add對這個map里的元素做任何的更新、刪除操作對調用方都是可見的。實際上就像在普通函數中一樣雖然可以通過引用來操作內部值但在方法想要脩改引用本身是不會影響原始值的比如把他置爲nil或者讓這個引用指向了其它的對象調用方都不會受影響。譯註因爲傳入的是存儲了內存地址的變量你改變這個變量是影響不了原始的變量的想想C語言是差不多的

View File

@@ -85,9 +85,9 @@ pptr.Distance(q) // implicit (*pptr)
如果類型T的所有方法都是用T類型自己來做接收器(而不是`*T`)那麽拷貝這種類型的實例就是安全的調用他的任何一個方法也就會産生一個值的拷貝。比如time.Duration的這個類型在調用其方法時就會被全部拷貝一份包括在作爲參數傳入函數的時候。但是如果一個方法使用指針作爲接收器你需要避免對其進行拷貝因爲這樣可能會破壞掉該類型內部的不變性。比如你對bytes.Buffer對象進行了拷貝那麽可能會引起原始對象和拷貝對象隻是别名而已但實際上其指向的對象是一致的。緊接着對拷貝後的變量進行脩改可能會有讓你意外的結果。
譯註:作者這里説的比較繞,其實有兩點:
**譯註:** 作者這里説的比較繞,其實有兩點:
1.不管你的method的receiver是指針類型還是非指針類型都是可以通過指針/非指針類型進行調用的,編譯器會幫你做類型轉換
2.在聲明一個method的receiver該是指針還是非指針類型時你需要考慮兩方面的內部第一方面是這個對象本身是不是特别大如果聲明爲非指針變量時調用會産生一次拷貝第二方面是如果你用指針類型作爲receiver那麽你一定要註意這種指針類型指向的始終是一塊內存地址就算你對其進行了拷貝。熟悉C或者C艹的人這里應該很快能明白。
1. 不管你的method的receiver是指針類型還是非指針類型都是可以通過指針/非指針類型進行調用的,編譯器會幫你做類型轉換
2. 在聲明一個method的receiver該是指針還是非指針類型時你需要考慮兩方面的內部第一方面是這個對象本身是不是特别大如果聲明爲非指針變量時調用會産生一次拷貝第二方面是如果你用指針類型作爲receiver那麽你一定要註意這種指針類型指向的始終是一塊內存地址就算你對其進行了拷貝。熟悉C或者C艹的人這里應該很快能明白。
{% include "./ch6-02-1.md" %}

View File

@@ -105,9 +105,9 @@ func (*IntSet) Clear() // remove all elements from the set
func (*IntSet) Copy() *IntSet // return a copy of the set
```
練習6.2: 定義一個變參方法(*IntSet).AddAll(...int)這個方法可以爲一組IntSet值求和比如s.AddAll(1,2,3)。
**練習 6.2** 定義一個變參方法(*IntSet).AddAll(...int)這個方法可以爲一組IntSet值求和比如s.AddAll(1,2,3)。
練習6.3: (*IntSet).UnionWith會用|操作符計算兩個集合的交集我們再爲IntSet實現另外的幾個函數IntersectWith(交集元素在A集合B集合均出現),DifferenceWith(差集元素出現在A集合未出現在B集合),SymmetricDifference(併差集元素出現在A但沒有出現在B或者出現在B沒有出現在A)。
**練習 6.3** (*IntSet).UnionWith會用|操作符計算兩個集合的交集我們再爲IntSet實現另外的幾個函數IntersectWith(交集元素在A集合B集合均出現),DifferenceWith(差集元素出現在A集合未出現在B集合),SymmetricDifference(併差集元素出現在A但沒有出現在B或者出現在B沒有出現在A)。
練習6.4: 實現一個Elems方法返迴集合中的所有元素用於做一些range之類的遍歷操作。
練習6.5: 我們這章定義的IntSet里的每個字都是用的uint64類型但是64位的數值可能在32位的平台上不高效。脩改程序使其使用uint類型這種類型對於32位平台來説更合適。當然了這里我們可以不用簡單粗暴地除64可以定義一個常量來決定是用32還是64這里你可能會用到平台的自動判斷的一個智能表達式32 << (^uint(0) >> 63)
**練習 6.5** 我們這章定義的IntSet里的每個字都是用的uint64類型但是64位的數值可能在32位的平台上不高效。脩改程序使其使用uint類型這種類型對於32位平台來説更合適。當然了這里我們可以不用簡單粗暴地除64可以定義一個常量來決定是用32還是64這里你可能會用到平台的自動判斷的一個智能表達式32 << (^uint(0) >> 63)