Compare commits

6 Commits

Author SHA1 Message Date
柴树杉
6ecbba5baa Merge pull request #247 from Nyvryl/Nyvryl-patch-1
Some checks failed
mdbook / deploy (push) Has been cancelled
Revise chapter 5.5 on function values in Go
2025-11-16 20:46:39 +08:00
Nyvryl
522457fa25 Revise chapter 5.5 on function values in Go
此处应为 "forEachNode" 而非 ”forEachNoded“,后者在前文中完全没有提及,应为笔误。
2025-11-16 11:13:04 +00:00
柴树杉
c58743acce Merge pull request #245 from lin-snow/patch-2
Some checks failed
mdbook / deploy (push) Has been cancelled
docs: add note about compile-time interface checks
2025-09-03 16:59:51 +08:00
柴树杉
cc738922ed Merge pull request #246 from lin-snow/patch-3
fix(docs): 更正术语“先觉条件”为“先决条件”
2025-09-03 16:59:14 +08:00
L1nSn0w
c080b2ac6d docs: 将“先觉条件”更正为“先决条件”,以符合技术语境 2025-09-03 09:52:02 +08:00
L1nSn0w
1ed9861965 Document conditions for implementing interfaces
Add section on interface implementation conditions
2025-09-03 09:10:55 +08:00
3 changed files with 6 additions and 3 deletions

View File

@@ -119,7 +119,7 @@ $ ./outline2 http://gopl.io
**练习 5.7** 完善startElement和endElement函数使其成为通用的HTML输出器。要求输出注释结点文本结点以及每个元素的属性< a href='...'>)。使用简略格式输出没有孩子结点的元素(即用`<img/>`代替`<img></img>`。编写测试验证程序输出的格式正确。详见11章
**练习 5.8** 修改pre和post函数使其返回布尔类型的返回值。返回false时中止forEachNoded的遍历。使用修改后的代码编写ElementByID函数根据用户输入的id查找第一个拥有该id元素的HTML元素查找成功后停止遍历。
**练习 5.8** 修改pre和post函数使其返回布尔类型的返回值。返回false时中止forEachNode的遍历。使用修改后的代码编写ElementByID函数根据用户输入的id查找第一个拥有该id元素的HTML元素查找成功后停止遍历。
```Go
func ElementByID(doc *html.Node, id string) *html.Node
@@ -130,3 +130,4 @@ func ElementByID(doc *html.Node, id string) *html.Node
```Go
func expand(s string, f func(string) string) string
```

View File

@@ -79,7 +79,7 @@ any = new(bytes.Buffer)
对于创建的一个interface{}值持有一个booleanfloatstringmappointer或者任意其它的类型我们当然不能直接对它持有的值做操作因为interface{}没有任何方法。我们会在7.10章中学到一种用类型断言来获取interface{}中值的方法。
因为接口与实现只依赖于判断两个类型的方法,所以没有必要定义一个具体类型和它实现的接口之间的关系。也就是说,有意地在文档里说明或者程序上断言这种关系偶尔是有用的,但程序上不强制这么做。下面的定义在编译期断言一个`*bytes.Buffer`的值实现了io.Writer接口类型:
因为接口与实现只依赖于判断两个类型的方法,所以没有必要定义一个具体类型和它实现的接口之间的关系。也就是说,有意地在文档里说明或者程序上断言这种关系偶尔是有用的,但程序上不强制这么做。这种写法还可用于让编译器在编译期确保某个类型确实满足接口要求,从而提前发现实现遗漏或接口变更导致的不匹配问题。下面的定义在编译期断言一个`*bytes.Buffer`的值实现了io.Writer接口类型:
```go
// *bytes.Buffer must satisfy io.Writer
@@ -150,3 +150,4 @@ type Streamer interface {
```
每一个具体类型的组基于它们相同的行为可以表示成一个接口类型。不像基于类的语言他们一个类实现的接口集合需要进行显式的定义在Go语言中我们可以在需要的时候定义一个新的抽象或者特定特点的组而不需要修改具体类型的定义。当具体的类型来自不同的作者时这种方式会特别有用。当然也确实没有必要在具体的类型中指出这些共性。

View File

@@ -151,7 +151,7 @@ if out != nil {
动态分配机制依然决定(\*bytes.Buffer).Write的方法会被调用但是这次的接收者的值是nil。对于一些如\*os.File的类型nil是一个有效的接收者§6.2.1),但是\*bytes.Buffer类型不在这些种类中。这个方法会被调用但是当它尝试去获取缓冲区时会发生panic。
问题在于尽管一个nil的\*bytes.Buffer指针有实现这个接口的方法它也不满足这个接口具体的行为上的要求。特别是这个调用违反了(\*bytes.Buffer).Write方法的接收者非空的隐含先条件所以将nil指针赋给这个接口是错误的。解决方案就是将main函数中的变量buf的类型改为io.Writer因此可以避免一开始就将一个不完整的值赋值给这个接口
问题在于尽管一个nil的\*bytes.Buffer指针有实现这个接口的方法它也不满足这个接口具体的行为上的要求。特别是这个调用违反了(\*bytes.Buffer).Write方法的接收者非空的隐含先条件所以将nil指针赋给这个接口是错误的。解决方案就是将main函数中的变量buf的类型改为io.Writer因此可以避免一开始就将一个不完整的值赋值给这个接口
```go
var buf io.Writer
@@ -162,3 +162,4 @@ f(buf) // OK
```
现在我们已经把接口值的技巧都讲完了让我们来看更多的一些在Go标准库中的重要接口类型。在下面的三章中我们会看到接口类型是怎样用在排序web服务错误处理中的。