mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-12-20 12:44:20 +08:00
fmr code
This commit is contained in:
@@ -69,6 +69,7 @@ func (s *IntSet) String() string {
|
||||
這里留意一下String方法,是不是和3.5.4節中的intsToString方法很相似;bytes.Buffer在String方法里經常這麽用。當你爲一個複雜的類型定義了一個String方法時,fmt包就會特殊對待這種類型的值,這樣可以讓這些類型在打印的時候看起來更加友好,而不是直接打印其原始的值。fmt會直接調用用戶定義的String方法。這種機製依賴於接口和類型斷言,在第7章中我們會詳細介紹。
|
||||
|
||||
現在我們就可以在實戰中直接用上面定義好的IntSet了:
|
||||
|
||||
```go
|
||||
var x, y IntSet
|
||||
x.Add(1)
|
||||
@@ -86,14 +87,17 @@ fmt.Println(x.Has(9), x.Has(123)) // "true false"
|
||||
```
|
||||
|
||||
這里要註意:我們聲明的String和Has兩個方法都是以指針類型*IntSet來作爲接收器的,但實際上對於這兩個類型來説,把接收器聲明爲指針類型也沒什麽必要。不過另外兩個函數就不是這樣了,因爲另外兩個函數操作的是s.words對象,如果你不把接收器聲明爲指針對象,那麽實際操作的是拷貝對象,而不是原來的那個對象。因此,因爲我們的String方法定義在IntSet指針上,所以當我們的變量是IntSet類型而不是IntSet指針時,可能會有下面這樣讓人意外的情況:
|
||||
|
||||
```go
|
||||
fmt.Println(&x) // "{1 9 42 144}"
|
||||
fmt.Println(x.String()) // "{1 9 42 144}"
|
||||
fmt.Println(x) // "{[4398046511618 0 65536]}"
|
||||
```
|
||||
|
||||
在第一個Println中,我們打印一個*IntSet的指針,這個類型的指針確實有自定義的String方法。第二Println,我們直接調用了x變量的String()方法;這種情況下編譯器會隱式地在x前插入&操作符,這樣相當遠我們還是調用的IntSet指針的String方法。在第三個Println中,因爲IntSet類型沒有String方法,所以Println方法會直接以原始的方式理解併打印。所以在這種情況下&符號是不能忘的。在我們這種場景下,你把String方法綁定到IntSet對象上,而不是IntSet指針上可能會更合適一些,不過這也需要具體問題具體分析。
|
||||
|
||||
練習6.1: 爲bit數組實現下面這些方法
|
||||
|
||||
```go
|
||||
func (*IntSet) Len() int // return the number of elements
|
||||
func (*IntSet) Remove(x int) // remove x from the set
|
||||
|
||||
Reference in New Issue
Block a user