ch6: fix code format

This commit is contained in:
chai2010 2016-01-21 10:08:07 +08:00
parent 20a8cf71b9
commit 2420954025
7 changed files with 90 additions and 88 deletions

View File

@ -4,8 +4,8 @@
下面來寫我們第一個方法的例子這個例子在package geometry下 下面來寫我們第一個方法的例子這個例子在package geometry下
<u><i>gopl.io/ch6/geometry</i></u>
```go ```go
gopl.io/ch6/geometry
package geometry package geometry
import "math" import "math"
@ -14,15 +14,13 @@ type Point struct{ X, Y float64 }
// traditional function // traditional function
func Distance(p, q Point) float64 { 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 // same thing, but as a method of the Point type
func (p Point) Distance(q Point) float64 { 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),早期的面向對象語言留下的遺産將調用一個方法稱爲“向一個對象發送消息”。 上面的代碼里那個附加的參數p叫做方法的接收器(receiver),早期的面向對象語言留下的遺産將調用一個方法稱爲“向一個對象發送消息”。

View File

@ -6,15 +6,15 @@
// An IntList is a linked list of integers. // An IntList is a linked list of integers.
// A nil *IntList represents the empty list. // A nil *IntList represents the empty list.
type IntList struct { type IntList struct {
Value int Value int
Tail *IntList Tail *IntList
} }
// Sum returns the sum of the list elements. // Sum returns the sum of the list elements.
func (list *IntList) Sum() int { func (list *IntList) Sum() int {
if list == nil { if list == nil {
return 0 return 0
} }
return list.Value + list.Tail.Sum() return list.Value + list.Tail.Sum()
} }
``` ```
@ -22,8 +22,8 @@ func (list *IntList) Sum() int {
下面是net/url包里Values類型定義的一部分。 下面是net/url包里Values類型定義的一部分。
<u><i>net/url</i></u>
```go ```go
net/url
package url package url
// Values maps a string key to a list of values. // 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, // Get returns the first value associated with the given key,
// or "" if there are none. // or "" if there are none.
func (v Values) Get(key string) string { func (v Values) Get(key string) string {
if vs := v[key]; len(vs) > 0 { if vs := v[key]; len(vs) > 0 {
return vs[0] return vs[0]
} }
return "" return ""
} }
// Add adds the value to key. // Add adds the value to key.
// It appends to any existing values associated with key. // It appends to any existing values associated with key.
func (v Values) Add(key, value string) { 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]等等),也可以使用這里提供的操作方法,或者兩者併用,都是可以的: 這個定義向外部暴露了一個map的類型的變量併且提供了一些能夠簡單操作這個map的方法。這個map的value字段是一個string的slice所以這個Values是一個多維map。客戶端使用這個變量的時候可以使用map固有的一些操作(make切片m[key]等等),也可以使用這里提供的操作方法,或者兩者併用,都是可以的:
<u><i>gopl.io/ch6/urlvalues</i></u>
```go ```go
gopl.io/ch6/urlvalues
m := url.Values{"lang": {"en"}} // direct construction m := url.Values{"lang": {"en"}} // direct construction
m.Add("item", "1") m.Add("item", "1")
m.Add("item", "2") m.Add("item", "2")

View File

@ -4,8 +4,8 @@
```go ```go
func (p *Point) ScaleBy(factor float64) { func (p *Point) ScaleBy(factor float64) {
p.X *= factor p.X *= factor
p.Y *= factor p.Y *= factor
} }
``` ```
@ -27,6 +27,7 @@ r := &Point{1, 2}
r.ScaleBy(2) r.ScaleBy(2)
fmt.Println(*r) // "{2, 4}" fmt.Println(*r) // "{2, 4}"
``` ```
或者這樣: 或者這樣:
```go ```go

View File

@ -2,13 +2,15 @@
來看看ColoredPoint這個類型 來看看ColoredPoint這個類型
<u><i>gopl.io/ch6/coloredpoint</i></u>
```go ```go
gopl.io/ch6/coloredpoint
import "image/color" import "image/color"
type Point struct{ X, Y float64 } type Point struct{ X, Y float64 }
type ColoredPoint struct { type ColoredPoint struct {
Point Point
Color color.RGBA Color color.RGBA
} }
``` ```
@ -47,11 +49,11 @@ p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point
```go ```go
func (p ColoredPoint) Distance(q Point) float64 { func (p ColoredPoint) Distance(q Point) float64 {
return p.Point.Distance(q) return p.Point.Distance(q)
} }
func (p *ColoredPoint) ScaleBy(factor float64) { 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 ```go
type ColoredPoint struct { type ColoredPoint struct {
*Point *Point
Color color.RGBA Color color.RGBA
} }
p := ColoredPoint{&Point{1, 1}, red} p := ColoredPoint{&Point{1, 1}, red}
@ -77,10 +79,11 @@ fmt.Println(*p.Point, *q.Point) // "{2 2} {2 2}"
```go ```go
type ColoredPoint struct { type ColoredPoint struct {
Point Point
color.RGBA color.RGBA
} }
``` ```
然後這種類型的值便會擁有Point和RGBA類型的所有方法以及直接定義在ColoredPoint中的方法。當編譯器解析一個選擇器到方法時比如p.ScaleBy它會首先去找直接定義在這個類型里的ScaleBy方法然後找被ColoredPoint的內嵌字段們引入的方法然後去找Point和RGBA的內嵌字段引入的方法然後一直遞歸向下找。如果選擇器有二義性的話編譯器會報錯比如你在同一級里有兩個同名的方法。 然後這種類型的值便會擁有Point和RGBA類型的所有方法以及直接定義在ColoredPoint中的方法。當編譯器解析一個選擇器到方法時比如p.ScaleBy它會首先去找直接定義在這個類型里的ScaleBy方法然後找被ColoredPoint的內嵌字段們引入的方法然後去找Point和RGBA的內嵌字段引入的方法然後一直遞歸向下找。如果選擇器有二義性的話編譯器會報錯比如你在同一級里有兩個同名的方法。
方法隻能在命名類型(像Point)或者指向類型的指針上定義但是多虧了內嵌有些時候我們給匿名struct類型來定義方法也有了手段。 方法隻能在命名類型(像Point)或者指向類型的指針上定義但是多虧了內嵌有些時候我們給匿名struct類型來定義方法也有了手段。
@ -89,15 +92,15 @@ type ColoredPoint struct {
```go ```go
var ( var (
mu sync.Mutex // guards mapping mu sync.Mutex // guards mapping
mapping = make(map[string]string) mapping = make(map[string]string)
) )
func Lookup(key string) string { func Lookup(key string) string {
mu.Lock() mu.Lock()
v := mapping[key] v := mapping[key]
mu.Unlock() mu.Unlock()
return v return v
} }
``` ```
@ -105,18 +108,18 @@ func Lookup(key string) string {
```go ```go
var cache = struct { var cache = struct {
sync.Mutex sync.Mutex
mapping map[string]string mapping map[string]string
}{ }{
mapping: make(map[string]string), mapping: make(map[string]string),
} }
func Lookup(key string) string { func Lookup(key string) string {
cache.Lock() cache.Lock()
v := cache.mapping[key] v := cache.mapping[key]
cache.Unlock() cache.Unlock()
return v return v
} }
``` ```

View File

@ -68,15 +68,15 @@ func (p Point) Sub(q Point) Point { return Point{p.X - q.X, p.Y - q.Y} }
type Path []Point type Path []Point
func (path Path) TranslateBy(offset Point, add bool) { func (path Path) TranslateBy(offset Point, add bool) {
var op func(p, q Point) Point var op func(p, q Point) Point
if add { if add {
op = Point.Add op = Point.Add
} else { } else {
op = Point.Sub op = Point.Sub
} }
for i := range path { for i := range path {
// Call either path[i].Add(offset) or path[i].Sub(offset). // Call either path[i].Add(offset) or path[i].Sub(offset).
path[i] = op(path[i], offset) path[i] = op(path[i], offset)
} }
} }
``` ```

View File

@ -4,38 +4,38 @@ Go語言里的集合一般會用map[T]bool這種形式來表示T代表元素
一個bit數組通常會用一個無符號數或者稱之爲“字”的slice或者來表示每一個元素的每一位都表示集合里的一個值。當集合的第i位被設置時我們才説這個集合包含元素i。下面的這個程序展示了一個簡單的bit數組類型併且實現了三個函數來對這個bit數組來進行操作 一個bit數組通常會用一個無符號數或者稱之爲“字”的slice或者來表示每一個元素的每一位都表示集合里的一個值。當集合的第i位被設置時我們才説這個集合包含元素i。下面的這個程序展示了一個簡單的bit數組類型併且實現了三個函數來對這個bit數組來進行操作
<u><i>gopl.io/ch6/intset</i></u>
```go ```go
gopl.io/ch6/intset
// An IntSet is a set of small non-negative integers. // An IntSet is a set of small non-negative integers.
// Its zero value represents the empty set. // Its zero value represents the empty set.
type IntSet struct { type IntSet struct {
words []uint64 words []uint64
} }
// Has reports whether the set contains the non-negative value x. // Has reports whether the set contains the non-negative value x.
func (s *IntSet) Has(x int) bool { func (s *IntSet) Has(x int) bool {
word, bit := x/64, uint(x%64) word, bit := x/64, uint(x%64)
return word < len(s.words) && s.words[word]&(1<<bit) != 0 return word < len(s.words) && s.words[word]&(1<<bit) != 0
} }
// Add adds the non-negative value x to the set. // Add adds the non-negative value x to the set.
func (s *IntSet) Add(x int) { func (s *IntSet) Add(x int) {
word, bit := x/64, uint(x%64) word, bit := x/64, uint(x%64)
for word >= len(s.words) { for word >= len(s.words) {
s.words = append(s.words, 0) s.words = append(s.words, 0)
} }
s.words[word] |= 1 << bit s.words[word] |= 1 << bit
} }
// UnionWith sets s to the union of s and t. // UnionWith sets s to the union of s and t.
func (s *IntSet) UnionWith(t *IntSet) { func (s *IntSet) UnionWith(t *IntSet) {
for i, tword := range t.words { for i, tword := range t.words {
if i < len(s.words) { if i < len(s.words) {
s.words[i] |= tword s.words[i] |= tword
} else { } else {
s.words = append(s.words, tword) s.words = append(s.words, tword)
} }
} }
} }
``` ```
@ -46,23 +46,23 @@ func (s *IntSet) UnionWith(t *IntSet) {
```go ```go
// String returns the set as a string of the form "{1 2 3}". // String returns the set as a string of the form "{1 2 3}".
func (s *IntSet) String() string { func (s *IntSet) String() string {
var buf bytes.Buffer var buf bytes.Buffer
buf.WriteByte('{') buf.WriteByte('{')
for i, word := range s.words { for i, word := range s.words {
if word == 0 { if word == 0 {
continue continue
} }
for j := 0; j < 64; j++ { for j := 0; j < 64; j++ {
if word&(1<<uint(j)) != 0 { if word&(1<<uint(j)) != 0 {
if buf.Len() > len("{") { if buf.Len() > len("{") {
buf.WriteByte('}') buf.WriteByte('}')
} }
fmt.Fprintf(&buf, "%d", 64*i+j)"}")}} fmt.Fprintf(&buf, "%d", 64*i+j)"}")}}
} }
} }
} }
buf.WriteByte('}') buf.WriteByte('}')
return buf.String() return buf.String()
} }
``` ```

View File

@ -63,9 +63,9 @@ func (c *Counter) Reset() { c.n = 0 }
```go ```go
package log package log
type Logger struct { type Logger struct {
flags int flags int
prefix string prefix string
// ... // ...
} }
func (l *Logger) Flags() int func (l *Logger) Flags() int
func (l *Logger) SetFlags(flag int) func (l *Logger) SetFlags(flag int)