第十章修改 (#840)

Co-authored-by: Joe Chen <jc@unknwon.io>
This commit is contained in:
Haigang Zhou
2022-05-11 22:58:19 +08:00
committed by GitHub
parent 471d59af32
commit d3979794f4
9 changed files with 108 additions and 106 deletions

View File

@@ -2,7 +2,8 @@
当定义了一个有很多方法的类型时,十之八九你会使用 `String()` 方法来定制类型的字符串形式的输出,换句话说:一种可阅读性和打印性的输出。如果类型定义了 `String()` 方法,它会被用在 `fmt.Printf()` 中生成默认的输出:等同于使用格式化描述符 `%v` 产生的输出。还有 `fmt.Print()``fmt.Println()` 也会自动使用 `String()` 方法。
我们使用第 10.4 节中程序的类型来进行测试:
我们使用[第 10.4 节](10.4.md)中程序的类型来进行测试:
示例 10.22 [method_string.go](examples/chapter_10/method_string.go)
@@ -45,7 +46,8 @@ func (tn *TwoInts) String() string {
**备注**
不要在 `String()` 方法里面调用涉及 `String()` 方法的方法,它会导致意料之外的错误,比如下面的例子,它导致了一个无限递归调用(`TT.String()` 调用 `fmt.Sprintf`,而 `fmt.Sprintf` 又会反过来调用 `TT.String()`...),很快就会导致内存溢出:
不要在 `String()` 方法里面调用涉及 `String()` 方法的方法,它会导致意料之外的错误,比如下面的例子,它导致了一个无限递归调用(`TT.String()` 调用 `fmt.Sprintf`,而 `fmt.Sprintf` 又会反过来调用 `TT.String()`),很快就会导致内存溢出:
```go
type TT float64
@@ -56,9 +58,9 @@ func (t TT) String() string {
t.String()
```
**练习 10.12** type_string.go
**练习 10.12** [type_string.go](exercises\chapter_10\type_string.go)
给定结构体类型 T:
给定结构体类型 `T`:
```go
type T struct {
@@ -70,40 +72,40 @@ type T struct {
`t`: `t := &T{7, -2.35, "abc\tdef"}`。给 T 定义 `String()`,使得 `fmt.Printf("%v\n", t)` 输出:`7 / -2.350000 / "abc\tdef"`
**练习 10.13** celsius.go
**练习 10.13** [celsius.go](exercises\chapter_10\celsius.go)
为 float64 定义一个别名类型 `Celsius`,并给它定义 `String()`,它输出一个十进制数和 °C 表示的温度值。
`float64` 定义一个别名类型 `Celsius`,并给它定义 `String()`,它输出一个十进制数和 °C 表示的温度值。
**练习 10.14** days.go
**练习 10.14** [days.go](exercises\chapter_10\days.go)
为 int 定义一个别名类型 `Day`,定义一个字符串数组它包含一周七天的名字,为类型 `Day` 定义 `String()` 方法,它输出星期几的名字。使用 `iota` 定义一个枚举常量用于表示一周的中每天MO、TU...)。
`int` 定义一个别名类型 `Day`,定义一个字符串数组它包含一周七天的名字,为类型 `Day` 定义 `String()` 方法,它输出星期几的名字。使用 `iota` 定义一个枚举常量用于表示一周的中每天MO、TU...)。
**练习 10.15** timezones.go
**练习 10.15** [timezones.go](exercises\chapter_10\timezones.go)
为 int 定义别名类型 `TZ`,定义一些常量表示时区,比如 UTC定义一个 map它将时区的缩写映射为它的全称比如`UTC -> "Universal Greenwich time"`。为类型 `TZ` 定义 `String()` 方法,它输出时区的全称。
`int` 定义别名类型 `TZ`,定义一些常量表示时区,比如 UTC定义一个 `map`,它将时区的缩写映射为它的全称,比如:`UTC -> "Universal Greenwich time"`。为类型 `TZ` 定义 `String()` 方法,它输出时区的全称。
**练习 10.16** stack_arr.go/stack_struct.go
**练习 10.16** [stack_arr.go](exercises\chapter_10\stack_arr.go) / [stack_struct.go](exercises\chapter_10\stack_struct.go)
实现栈stack数据结构:
实现栈 (stack) 数据结构:
![](images/10.7_fig.jpg?raw=true)
它的格子包含数据,比如整数 i、j、k 和 l 等等,格子从底部(索引 0至顶部索引 n来索引。这个例子中假定 `n = 3`,那么一共有 4 个格子。
它的格子包含数据,比如整数 `i``j``k``l` 等等,格子从底部(索引 0至顶部索引 n来索引。这个例子中假定 `n = 3`,那么一共有 4 个格子。
一个新栈中所有格子的值都是 0
一个新栈中所有格子的值都是 `0`
将一个新值放到栈的最顶部一个空(包括零)的格子中,这叫做`push`
将一个新值放到栈的最顶部一个空(包括零)的格子中,这叫做 push。
获取栈的最顶部一个非空(非零)的格子的值,这叫做`pop`
现在可以理解为什么栈是一个后进先出LIFO的结构了吧。
获取栈的最顶部一个非空(非零)的格子的值,这叫做 pop。
现在可以理解为什么栈是一个后进先出 (LIFO) 的结构了吧。
为栈定义一个`Stack` 类型,并为它定义 `Push``Pop` 方法,再为它定义 `String()` 方法(用于调试)输出栈的内容,比如:`[0:i] [1:j] [2:k] [3:l]`
为栈定义一个 `Stack` 类型,并为它定义 `Push``Pop` 方法,再为它定义 `String()` 方法(用于调试)输出栈的内容,比如:`[0:i] [1:j] [2:k] [3:l]`
1stack_arr.go使用长度为 4 的 int 数组作为底层数据结构。
1[stack_arr.go](exercises\chapter_10\stack_arr.go):使用长度为 4 的 int 数组作为底层数据结构。
2stack_struct.go使用包含一个索引和一个 int 数组的结构体作为底层数据结构,索引表示第一个空闲的位置。
2 [stack_struct.go](exercises\chapter_10\stack_struct.go):使用包含一个索引和一个 `int` 数组的结构体作为底层数据结构,索引表示第一个空闲的位置。
3使用常量 LIMIT 代替上面表示元素个数的 4 重新实现上面的 1和 2使它们更具有一般性。
3使用常量 `LIMIT` 代替上面表示元素个数的 4 重新实现上面的 1和 2使它们更具有一般性。
## 链接