diff --git a/ch6/ch6-01.md b/ch6/ch6-01.md
index e2a7f2a..b619b6a 100644
--- a/ch6/ch6-01.md
+++ b/ch6/ch6-01.md
@@ -4,8 +4,8 @@
下面來寫我們第一個方法的例子,這個例子在package geometry下:
+gopl.io/ch6/geometry
```go
-gopl.io/ch6/geometry
package geometry
import "math"
@@ -14,15 +14,13 @@ type Point struct{ X, Y float64 }
// traditional function
func Distance(p, q Point) float64 {
- return math.Hypot(q.X-p.X, q.Y-p.Y)
+ return math.Hypot(q.X-p.X, q.Y-p.Y)
}
-
// same thing, but as a method of the Point type
func (p Point) Distance(q Point) float64 {
- return math.Hypot(q.X-p.X, q.Y-p.Y)
+ return math.Hypot(q.X-p.X, q.Y-p.Y)
}
-
```
上面的代碼里那個附加的參數p,叫做方法的接收器(receiver),早期的面向對象語言留下的遺産將調用一個方法稱爲“向一個對象發送消息”。
diff --git a/ch6/ch6-02-1.md b/ch6/ch6-02-1.md
index ed29486..38dbbdb 100644
--- a/ch6/ch6-02-1.md
+++ b/ch6/ch6-02-1.md
@@ -6,15 +6,15 @@
// An IntList is a linked list of integers.
// A nil *IntList represents the empty list.
type IntList struct {
- Value int
- Tail *IntList
+ Value int
+ Tail *IntList
}
// Sum returns the sum of the list elements.
func (list *IntList) Sum() int {
- if list == nil {
- return 0
- }
- return list.Value + list.Tail.Sum()
+ if list == nil {
+ return 0
+ }
+ return list.Value + list.Tail.Sum()
}
```
@@ -22,8 +22,8 @@ func (list *IntList) Sum() int {
下面是net/url包里Values類型定義的一部分。
+net/url
```go
-net/url
package url
// Values maps a string key to a list of values.
@@ -31,22 +31,22 @@ type Values map[string][]string
// Get returns the first value associated with the given key,
// or "" if there are none.
func (v Values) Get(key string) string {
- if vs := v[key]; len(vs) > 0 {
- return vs[0]
- }
- return ""
+ if vs := v[key]; len(vs) > 0 {
+ return vs[0]
+ }
+ return ""
}
// Add adds the value to key.
// It appends to any existing values associated with key.
func (v Values) Add(key, value string) {
- v[key] = append(v[key], value)
+ v[key] = append(v[key], value)
}
```
這個定義向外部暴露了一個map的類型的變量,併且提供了一些能夠簡單操作這個map的方法。這個map的value字段是一個string的slice,所以這個Values是一個多維map。客戶端使用這個變量的時候可以使用map固有的一些操作(make,切片,m[key]等等),也可以使用這里提供的操作方法,或者兩者併用,都是可以的:
+gopl.io/ch6/urlvalues
```go
-gopl.io/ch6/urlvalues
m := url.Values{"lang": {"en"}} // direct construction
m.Add("item", "1")
m.Add("item", "2")
diff --git a/ch6/ch6-02.md b/ch6/ch6-02.md
index f1bd299..5ab502d 100644
--- a/ch6/ch6-02.md
+++ b/ch6/ch6-02.md
@@ -4,8 +4,8 @@
```go
func (p *Point) ScaleBy(factor float64) {
- p.X *= factor
- p.Y *= factor
+ p.X *= factor
+ p.Y *= factor
}
```
@@ -27,6 +27,7 @@ r := &Point{1, 2}
r.ScaleBy(2)
fmt.Println(*r) // "{2, 4}"
```
+
或者這樣:
```go
diff --git a/ch6/ch6-03.md b/ch6/ch6-03.md
index 1e6a6b8..8b76a65 100644
--- a/ch6/ch6-03.md
+++ b/ch6/ch6-03.md
@@ -2,13 +2,15 @@
來看看ColoredPoint這個類型:
+gopl.io/ch6/coloredpoint
```go
-gopl.io/ch6/coloredpoint
import "image/color"
+
type Point struct{ X, Y float64 }
+
type ColoredPoint struct {
- Point
- Color color.RGBA
+ Point
+ Color color.RGBA
}
```
@@ -47,11 +49,11 @@ p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point
```go
func (p ColoredPoint) Distance(q Point) float64 {
- return p.Point.Distance(q)
+ return p.Point.Distance(q)
}
func (p *ColoredPoint) ScaleBy(factor float64) {
- p.Point.ScaleBy(factor)
+ p.Point.ScaleBy(factor)
}
```
@@ -61,8 +63,8 @@ func (p *ColoredPoint) ScaleBy(factor float64) {
```go
type ColoredPoint struct {
- *Point
- Color color.RGBA
+ *Point
+ Color color.RGBA
}
p := ColoredPoint{&Point{1, 1}, red}
@@ -77,10 +79,11 @@ fmt.Println(*p.Point, *q.Point) // "{2 2} {2 2}"
```go
type ColoredPoint struct {
- Point
- color.RGBA
+ Point
+ color.RGBA
}
```
+
然後這種類型的值便會擁有Point和RGBA類型的所有方法,以及直接定義在ColoredPoint中的方法。當編譯器解析一個選擇器到方法時,比如p.ScaleBy,它會首先去找直接定義在這個類型里的ScaleBy方法,然後找被ColoredPoint的內嵌字段們引入的方法,然後去找Point和RGBA的內嵌字段引入的方法,然後一直遞歸向下找。如果選擇器有二義性的話編譯器會報錯,比如你在同一級里有兩個同名的方法。
方法隻能在命名類型(像Point)或者指向類型的指針上定義,但是多虧了內嵌,有些時候我們給匿名struct類型來定義方法也有了手段。
@@ -89,15 +92,15 @@ type ColoredPoint struct {
```go
var (
- mu sync.Mutex // guards mapping
- mapping = make(map[string]string)
+ mu sync.Mutex // guards mapping
+ mapping = make(map[string]string)
)
func Lookup(key string) string {
- mu.Lock()
- v := mapping[key]
- mu.Unlock()
- return v
+ mu.Lock()
+ v := mapping[key]
+ mu.Unlock()
+ return v
}
```
@@ -105,18 +108,18 @@ func Lookup(key string) string {
```go
var cache = struct {
- sync.Mutex
- mapping map[string]string
+ sync.Mutex
+ mapping map[string]string
}{
- mapping: make(map[string]string),
+ mapping: make(map[string]string),
}
func Lookup(key string) string {
- cache.Lock()
- v := cache.mapping[key]
- cache.Unlock()
- return v
+ cache.Lock()
+ v := cache.mapping[key]
+ cache.Unlock()
+ return v
}
```
diff --git a/ch6/ch6-04.md b/ch6/ch6-04.md
index be944e5..18104cd 100644
--- a/ch6/ch6-04.md
+++ b/ch6/ch6-04.md
@@ -68,15 +68,15 @@ func (p Point) Sub(q Point) Point { return Point{p.X - q.X, p.Y - q.Y} }
type Path []Point
func (path Path) TranslateBy(offset Point, add bool) {
- var op func(p, q Point) Point
- if add {
- op = Point.Add
- } else {
- op = Point.Sub
- }
- for i := range path {
- // Call either path[i].Add(offset) or path[i].Sub(offset).
- path[i] = op(path[i], offset)
- }
+ var op func(p, q Point) Point
+ if add {
+ op = Point.Add
+ } else {
+ op = Point.Sub
+ }
+ for i := range path {
+ // Call either path[i].Add(offset) or path[i].Sub(offset).
+ path[i] = op(path[i], offset)
+ }
}
```
diff --git a/ch6/ch6-05.md b/ch6/ch6-05.md
index a015264..5aa2e13 100644
--- a/ch6/ch6-05.md
+++ b/ch6/ch6-05.md
@@ -4,38 +4,38 @@ Go語言里的集合一般會用map[T]bool這種形式來表示,T代表元素
一個bit數組通常會用一個無符號數或者稱之爲“字”的slice或者來表示,每一個元素的每一位都表示集合里的一個值。當集合的第i位被設置時,我們才説這個集合包含元素i。下面的這個程序展示了一個簡單的bit數組類型,併且實現了三個函數來對這個bit數組來進行操作:
+gopl.io/ch6/intset
```go
-gopl.io/ch6/intset
// An IntSet is a set of small non-negative integers.
// Its zero value represents the empty set.
type IntSet struct {
- words []uint64
+ words []uint64
}
// Has reports whether the set contains the non-negative value x.
func (s *IntSet) Has(x int) bool {
- word, bit := x/64, uint(x%64)
- return word < len(s.words) && s.words[word]&(1<= len(s.words) {
- s.words = append(s.words, 0)
- }
- s.words[word] |= 1 << bit
+ word, bit := x/64, uint(x%64)
+ for word >= len(s.words) {
+ s.words = append(s.words, 0)
+ }
+ s.words[word] |= 1 << bit
}
// UnionWith sets s to the union of s and t.
func (s *IntSet) UnionWith(t *IntSet) {
- for i, tword := range t.words {
- if i < len(s.words) {
- s.words[i] |= tword
- } else {
- s.words = append(s.words, tword)
- }
- }
+ for i, tword := range t.words {
+ if i < len(s.words) {
+ s.words[i] |= tword
+ } else {
+ s.words = append(s.words, tword)
+ }
+ }
}
```
@@ -46,23 +46,23 @@ func (s *IntSet) UnionWith(t *IntSet) {
```go
// String returns the set as a string of the form "{1 2 3}".
func (s *IntSet) String() string {
- var buf bytes.Buffer
- buf.WriteByte('{')
- for i, word := range s.words {
- if word == 0 {
- continue
- }
- for j := 0; j < 64; j++ {
- if word&(1< len("{") {
- buf.WriteByte('}')
- }
- fmt.Fprintf(&buf, "%d", 64*i+j)"}")}}
- }
- }
- }
- buf.WriteByte('}')
- return buf.String()
+ var buf bytes.Buffer
+ buf.WriteByte('{')
+ for i, word := range s.words {
+ if word == 0 {
+ continue
+ }
+ for j := 0; j < 64; j++ {
+ if word&(1< len("{") {
+ buf.WriteByte('}')
+ }
+ fmt.Fprintf(&buf, "%d", 64*i+j)"}")}}
+ }
+ }
+ }
+ buf.WriteByte('}')
+ return buf.String()
}
```
diff --git a/ch6/ch6-06.md b/ch6/ch6-06.md
index 272da94..0d30d53 100644
--- a/ch6/ch6-06.md
+++ b/ch6/ch6-06.md
@@ -63,9 +63,9 @@ func (c *Counter) Reset() { c.n = 0 }
```go
package log
type Logger struct {
- flags int
- prefix string
- // ...
+ flags int
+ prefix string
+ // ...
}
func (l *Logger) Flags() int
func (l *Logger) SetFlags(flag int)