mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2024-12-26 06:46:27 +00:00
ch6: fix code format
This commit is contained in:
parent
20a8cf71b9
commit
2420954025
@ -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),早期的面向對象語言留下的遺産將調用一個方法稱爲“向一個對象發送消息”。
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user