回到简体

This commit is contained in:
chai2010
2016-02-15 11:06:34 +08:00
parent 9e878f9944
commit 2b37b23285
177 changed files with 2354 additions and 2354 deletions

View File

@@ -1,10 +1,10 @@
## 7.1. 接口
## 7.1. 接口
目前止,我看到的型都是具體的類型。一個具體的類型可以準確的描述它所代表的值且展示出對類型本身的一些操作方式就像數字類型的算操作,切片型的索引、附加和取范操作。具體的類型還可以通它的方法提供外的行操作。總的來説,當你拿到一個具體的類型時你就知道它的本身是什和你可以用它做什
目前止,我看到的型都是具体的类型。一个具体的类型可以准确的描述它所代表的值且展示出对类型本身的一些操作方式就像数字类型的算操作,切片型的索引、附加和取范操作。具体的类型还可以通它的方法提供外的行操作。总的来说,当你拿到一个具体的类型时你就知道它的本身是什和你可以用它做什
在Go言中存在着另外一種類型:接口型。接口型是一抽象的型。它不暴露出它所代表的象的部值的結構和這個對象支持的基操作的集合;它們隻會展示出它自己的方法。也就是説當你有看到一接口型的值,你不知道它是什,唯一知道的就是可以通它的方法做什
在Go言中存在着另外一种类型:接口型。接口型是一抽象的型。它不暴露出它所代表的象的部值的结构和这个对象支持的基操作的集合;它们只会展示出它自己的方法。也就是说当你有看到一接口型的值,你不知道它是什,唯一知道的就是可以通它的方法做什
在本中,我一直使用兩個相似的函數來進行字符串的格式化fmt.Printf它會把結果寫到標準輸出和fmt.Sprintf它會把結果以字符串的形式返。得益使用接口,我不必可悲的因爲返迴結果在使用方式上的一些淺顯不同就必需把格式化這個最睏難的過程複製一份。實際上,這兩個函數都使用了另一個函數fmt.Fprintf來進行封。fmt.Fprintf這個函數對它的計算結果會被怎使用是完全不知道的。
在本中,我一直使用两个相似的函数来进行字符串的格式化fmt.Printf它会把结果写到标准输出和fmt.Sprintf它会把结果以字符串的形式返。得益使用接口,我不必可悲的因为返回结果在使用方式上的一些浅显不同就必需把格式化这个最困难的过程复制一份。实际上,这两个函数都使用了另一个函数fmt.Fprintf来进行封。fmt.Fprintf这个函数对它的计算结果会被怎使用是完全不知道的。
``` go
package fmt
@@ -20,10 +20,10 @@ func Sprintf(format string, args ...interface{}) string {
}
```
Fprintf的前F表示文件(File)也表明格式化輸出結果應該被寫入第一個參數提供的文件中。在Printf函中的第一個參數os.Stdout是*os.File在Sprintf函中的第一個參數&buf是一指向可以入字節的內存緩衝區,然而它
不是一文件類型盡管它在某種意義上和文件型相似。
Fprintf的前F表示文件(File)也表明格式化输出结果应该被写入第一个参数提供的文件中。在Printf函中的第一个参数os.Stdout是*os.File在Sprintf函中的第一个参数&buf是一指向可以入字节的内存缓冲区,然而它
不是一文件类型尽管它在某种意义上和文件型相似。
使Fprintf函中的第一個參數也不是一文件型。它是io.Writer類型這是一接口型定如下:
使Fprintf函中的第一个参数也不是一文件型。它是io.Writer类型这是一接口型定如下:
``` go
package io
@@ -41,11 +41,11 @@ type Writer interface {
}
```
io.Writer型定了函Fprintf和這個函數調用者之間的約定。一方面這個約定需要調用者提供具體類型的值就像\*os.File和\*bytes.Buffer這些類型都有一特定名和行的Write的函。另一方面這個約定保了Fprintf接受任何滿足io.Writer接口的值都可以工作。Fprintf函可能有假定入的是一文件或是一段存,而是入一可以調用Write函的值。
io.Writer型定了函Fprintf和这个函数调用者之间的约定。一方面这个约定需要用者提供具体类型的值就像\*os.File和\*bytes.Buffer这些类型都有一特定名和行的Write的函。另一方面这个约定保了Fprintf接受任何足io.Writer接口的值都可以工作。Fprintf函可能有假定入的是一文件或是一段存,而是入一可以用Write函的值。
fmt.Fprintf函數沒有對具體操作的值做任何假而是僅僅通過io.Writer接口的約定來保證行爲,所以第一個參數可以安全地入一任何具體類型的值需要滿足io.Writer接口。一個類型可以自由的使用另一個滿足相同接口的類型來進行替換被稱作可替性(LSP里氏替)。是一面向象的特
fmt.Fprintf函数没有对具体操作的值做任何假而是仅仅通过io.Writer接口的约定来保证行为,所以第一个参数可以安全地入一任何具体类型的值需要足io.Writer接口。一个类型可以自由的使用另一个满足相同接口的类型来进行替换被称作可替性(LSP里氏替)。是一面向象的特
讓我們通過一個新的類型來進行校,下面\*ByteCounter型里的Write方法僅僅在丟失寫向它的字節前統計它們的長度。(在這個+=賦值語句中,len(p)的型和\*c的型匹配的轉換是必的。)
让我们通过一个新的类型来进行校,下面\*ByteCounter型里的Write方法仅仅在丢失写向它的字节前统计它们的长度。(在这个+=赋值语句中,len(p)的型和\*c的型匹配的转换是必的。)
<u><i>gopl.io/ch7/bytecounter</i></u>
```go
@@ -57,7 +57,7 @@ func (c *ByteCounter) Write(p []byte) (int, error) {
}
```
*ByteCounter滿足io.Writer的定,我可以把它入Fprintf函Fprintf函數執行字符串格式化的程不會去關註ByteCounter正確的纍加結果的度。
*ByteCounter足io.Writer的定,我可以把它入Fprintf函Fprintf函数执行字符串格式化的程不会去关注ByteCounter正确的累加结果的度。
```go
var c ByteCounter
@@ -69,7 +69,7 @@ fmt.Fprintf(&c, "hello, %s", name)
fmt.Println(c) // "12", = len("hello, Dolly")
```
除了io.Writer這個接口型,有另一個對fmt包很重要的接口型。Fprintf和Fprintln函數向類型提供了一種控製它們值輸出的途。在2.5中,我們爲Celsius型提供了一String方法以便可以打印成這樣"100°C" 在6.5中我們給*IntSet添加一String方法這樣集合可以用傳統的符號來進行表示就像"{1 2 3}"。給一個類型定String方法可以讓它滿足最泛使用之一的接口型fmt.Stringer
除了io.Writer这个接口型,有另一个对fmt包很重要的接口型。Fprintf和Fprintln函数向类型提供了一种控制它们值输出的途。在2.5中,我们为Celsius型提供了一String方法以便可以打印成这样"100°C" 在6.5中我们给*IntSet添加一String方法这样集合可以用传统的符号来进行表示就像"{1 2 3}"。给一个类型定String方法可以让它满足最广泛使用之一的接口型fmt.Stringer
```go
package fmt
@@ -82,14 +82,14 @@ type Stringer interface {
}
```
們會在7.10節解釋fmt包怎麽發現哪些值是滿足這個接口型的。
们会在7.10节解释fmt包怎么发现哪些值是满足这个接口型的。
**練習 7.1** 使用自ByteCounter的思路實現一個針對對單詞和行數的計數器。你會發現bufio.ScanWords非常的有用。
**练习 7.1** 使用自ByteCounter的思路实现一个针对对单词和行数的计数器。你会发现bufio.ScanWords非常的有用。
**練習 7.2** 寫一個帶有如下函數籤名的函CountingWriter入一io.Writer接口型,返迴一個新的Writer型把原的Writer封在里面和一表示入新的Writer字節數的int64型指
**练习 7.2** 写一个带有如下函数签名的函CountingWriter入一io.Writer接口型,返回一个新的Writer型把原的Writer封在里面和一表示入新的Writer字节数的int64型指
```go
func CountingWriter(w io.Writer) (io.Writer, *int64)
```
**練習 7.3** 在gopl.io/ch4/treesort (§4.4)的*tree類型實現一個String方法去展示tree型的值序列。
**练习 7.3** 在gopl.io/ch4/treesort (§4.4)的*tree类型实现一个String方法去展示tree型的值序列。