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)