make loop

This commit is contained in:
chai2010 2016-01-03 20:35:38 +08:00
parent e0a5eb9474
commit 9787892cb0

View File

@ -20,7 +20,7 @@ rwc = w // compile error: io.Writer lacks Close method
``` ```
因爲ReadWriter和ReadWriteCloser包含所有Writer的方法所以任何實現了ReadWriter和ReadWriteCloser的類型必定也實現了Writer接口 因爲ReadWriter和ReadWriteCloser包含所有Writer的方法所以任何實現了ReadWriter和ReadWriteCloser的類型必定也實現了Writer接口
在進一步學習前必鬚先解釋表示一個類型持有一個方法當中的細節。迴想在6.2章中對於每一個命名過的具體類型T它一些方法的接收者是類型T本身然而另一些則是一個*T的指針。還記得在T類型的參數上調用一個*T的方法是合法的隻要這個參數是一個變量編譯器隱式的取了它的地址。但這僅僅是一個語法醣T類型的值不擁有所有*T指針的方法那這樣它就可能隻實現更少的接口。 在進一步學習前必鬚先解釋表示一個類型持有一個方法當中的細節。迴想在6.2章中對於每一個命名過的具體類型T它一些方法的接收者是類型T本身然而另一些則是一個*T的指針。還記得在T類型的參數上調用一個*T的方法是合法的隻要這個參數是一個變量編譯器隱式的取了它的地址。但這僅僅是一個語法醣T類型的值不擁有所有*T指針的方法那這樣它就可能隻實現更少的接口。
舉個例子可能會更清晰一點。在第6.5章中IntSet類型的String方法的接收者是一個指針類型所以我們不能在一個不能尋址的IntSet值上調用這個方法 舉個例子可能會更清晰一點。在第6.5章中IntSet類型的String方法的接收者是一個指針類型所以我們不能在一個不能尋址的IntSet值上調用這個方法
```go ```go
@ -38,9 +38,9 @@ var _ = s.String() // OK: s is a variable and &s has a String method
var _ fmt.Stringer = &s // OK var _ fmt.Stringer = &s // OK
var _ fmt.Stringer = s // compile error: IntSet lacks String method var _ fmt.Stringer = s // compile error: IntSet lacks String method
``` ```
12.8章包含了一個打印任意值的所有方法的程序然後可以使用godoc -analysis=type tool(§10.7.4)展示每個類型的方法和具體類型和接口之間的關繫 12.8章包含了一個打印任意值的所有方法的程序然後可以使用godoc -analysis=type tool(§10.7.4)展示每個類型的方法和具體類型和接口之間的關繫
就像信封封裝和隱藏信件起來一樣,接口類型封裝和隱藏具體類型和它的值。卽使具體類型有其它的方法也隻有接口類型暴露來的方法會被調用到: 就像信封封裝和隱藏信件起來一樣,接口類型封裝和隱藏具體類型和它的值。卽使具體類型有其它的方法也隻有接口類型暴露來的方法會被調用到:
```go ```go
os.Stdout.Write([]byte("hello")) // OK: *os.File has Write method os.Stdout.Write([]byte("hello")) // OK: *os.File has Write method
os.Stdout.Close() // OK: *os.File has Close method os.Stdout.Close() // OK: *os.File has Close method
@ -50,7 +50,7 @@ w = os.Stdout
w.Write([]byte("hello")) // OK: io.Writer has Write method w.Write([]byte("hello")) // OK: io.Writer has Write method
w.Close() // compile error: io.Writer lacks Close method w.Close() // compile error: io.Writer lacks Close method
``` ```
一個有更多方法的接口類型比如io.ReadWriter和少一些方法的接口類型,例如io.Reader進行對比更多方法的接口類型會告訴我們更多關於它的值持有的信息併且對實現它的類型要求更加嚴格。那麽關於interface{}類型,它沒有任何方法,請講哪些具體的類型實現了它? 一個有更多方法的接口類型比如io.ReadWriter和少一些方法的接口類型,例如io.Reader進行對比更多方法的接口類型會告訴我們更多關於它的值持有的信息併且對實現它的類型要求更加嚴格。那麽關於interface{}類型,它沒有任何方法,請講哪些具體的類型實現了它?
這看上去好像沒有用但實際上interface{}被稱爲空接口類型是不可或缺的。因爲空接口類型對實現它的類型沒有要求,所以我們可以將任意一個值賦給空接口類型。 這看上去好像沒有用但實際上interface{}被稱爲空接口類型是不可或缺的。因爲空接口類型對實現它的類型沒有要求,所以我們可以將任意一個值賦給空接口類型。
```go ```go
@ -63,7 +63,7 @@ any = new(bytes.Buffer)
``` ```
盡管不是很明顯從本書最早的的例子中我們就已經在使用空接口類型。它允許像fmt.Println或者5.7章中的errorf函數接受任何類型的參數。 盡管不是很明顯從本書最早的的例子中我們就已經在使用空接口類型。它允許像fmt.Println或者5.7章中的errorf函數接受任何類型的參數。
對於創建的一個interface{}值持有一個booleanfloatstringmappointer或者任意其它的類型我們當然不能直接對它持有的值做操作因爲interface{}沒有任何方法。我們會在7.10章中學到一種用類型斷言來取interface{}中值的方法。 對於創建的一個interface{}值持有一個booleanfloatstringmappointer或者任意其它的類型我們當然不能直接對它持有的值做操作因爲interface{}沒有任何方法。我們會在7.10章中學到一種用類型斷言來取interface{}中值的方法。
因爲接口實現隻依賴於判斷的兩個類型的方法,所以沒有必要定義一個具體類型和它實現的接口之間的關繫。也就是説,嚐試文檔化和斷言這種關繫幾乎沒有用,所以併沒有通過程序強製定義。下面的定義在編譯期斷言一個*bytes.Buffer的值實現了io.Writer接口類型: 因爲接口實現隻依賴於判斷的兩個類型的方法,所以沒有必要定義一個具體類型和它實現的接口之間的關繫。也就是説,嚐試文檔化和斷言這種關繫幾乎沒有用,所以併沒有通過程序強製定義。下面的定義在編譯期斷言一個*bytes.Buffer的值實現了io.Writer接口類型:
```go ```go
@ -79,7 +79,7 @@ var _ io.Writer = (*bytes.Buffer)(nil)
但是併不意味着隻有指針類型滿足接口類型甚至連一些有設置方法的接口類型也可能會被Go語言中其它的引用類型實現。我們已經看過slice類型的方法(geometry.Path, §6.1)和map類型的方法(url.Values, §6.2.1),後面還會看到函數類型的方法的例子(http.HandlerFunc, §7.7)。甚至基本的類型也可能會實現一些接口就如我們在7.4章中看到的time.Duration類型實現了fmt.Stringer接口。 但是併不意味着隻有指針類型滿足接口類型甚至連一些有設置方法的接口類型也可能會被Go語言中其它的引用類型實現。我們已經看過slice類型的方法(geometry.Path, §6.1)和map類型的方法(url.Values, §6.2.1),後面還會看到函數類型的方法的例子(http.HandlerFunc, §7.7)。甚至基本的類型也可能會實現一些接口就如我們在7.4章中看到的time.Duration類型實現了fmt.Stringer接口。
一個具體的類型可能實現了很多不相關的接口。考慮在一個組織售數字文化産品比如音樂,電影和書籍的程序中可能定義了下列的具體類型: 一個具體的類型可能實現了很多不相關的接口。考慮在一個組織售數字文化産品比如音樂,電影和書籍的程序中可能定義了下列的具體類型:
``` go ``` go
Album Album
Book Book
@ -97,7 +97,7 @@ type Artifact interface {
Created() time.Time Created() time.Time
} }
``` ```
其它的一些特性隻對特定類型的文化産品有。和文字排版特性相關的隻有books和magazines還有隻有movies和TV劇集和屏幕分辨率相關。 其它的一些特性隻對特定類型的文化産品有。和文字排版特性相關的隻有books和magazines還有隻有movies和TV劇集和屏幕分辨率相關。
```go ```go
type Text interface { type Text interface {
Pages() int Pages() int
@ -124,4 +124,4 @@ type Streamer interface {
Format() string Format() string
} }
``` ```
每一個具體類型的組基於它們相同的行爲可以表示成一個接口類型。不像基於類的語言他們一個類實現的接口集合需要進行顯式的定義在Go語言中我們可以在需要的時候定義一個新的抽象或者特定特點的組而不需要脩改具體類型的定義。當具體的類型來自不同的作者時這種方式會特别有用。當然也確實沒有必要在具體的類型中指這些共性。 每一個具體類型的組基於它們相同的行爲可以表示成一個接口類型。不像基於類的語言他們一個類實現的接口集合需要進行顯式的定義在Go語言中我們可以在需要的時候定義一個新的抽象或者特定特點的組而不需要脩改具體類型的定義。當具體的類型來自不同的作者時這種方式會特别有用。當然也確實沒有必要在具體的類型中指這些共性。