leisore 10 жил өмнө
parent
commit
efc961c20e

+ 95 - 3
eBook/10.1.md

@@ -209,11 +209,103 @@ type Rect2 struct {Min, Max *Point }
 
 **递归结构体**
 
-**练习9.2**
+结构体类型可以通过自身来定义。在结构体变量是链表或二叉树的元素(通常叫节点)时,这种方法会特别有用,此时节点包含指向临近节点的链接(地址)。如下所示,链表中的`su`,树中的`ri`h和`le`分别是指向另一个节点变量的指针。
 
-通过使用 unsafe 包中的方法来测试你电脑上一个整型变量占用多少个字节。
+链表:
+
+![](images/10.1_fig10.3.jpg?raw=true)
+
+这块的data域用于存放有些数据(比如float64),su指针指向后继节点。
+
+Go代码:
+
+```go
+type Node struct {
+    data float64
+    su   *Node
+}
+```
+
+链表中的第一个元素叫`head`,它指向第二个元素;最后一个元素叫`tail`,它没有后继元素,所以它的su为nil值。当然真实的链接会有很多数据节点,并且链表可以动态增长或收缩。
+
+同样地可以定义一个双向链表,它有一个前趋节点pr和一个后继节点su:
+
+```go
+type Node struct {
+    pr      *Node
+    data    float64
+    su      *su
+}
+```
+
+二叉树:
+
+![](images/10.1_fig10.4.jpg?raw=true)
+
+二叉树中每个节点最多能链接至两个节点:左节点(le)和右节点(ri),这两个节点本身又可以有左右节点,依次类推。树的顶层节点叫根节点(`root`),底层没有子节点的节点叫叶子节点(`leaves`),叶子节点的le和ri指针为空值。在Go中可以如下定义树:
+
+```go
+type Tree strcut {
+    le      *Tree
+    data    float64
+    ri      *Tree
+}
+```
+
+**结构体转换**
+
+Go中的类型转换遵循严格的规则。当为结构体定义了一个alias类型时,此结构体类型和它的alias类型都有相同的底层类型,它们可以如[Listing  10.3]那样互相转换,同时需要注意其中非法赋值或转换引起的编译错误:
+
+```go
+package main
+import "fmt"
+
+type number struct {
+    f float32
+}
+
+type nr number   // alias type
+
+func main() {
+    a := number{5.0}
+    b := nr{5.0}
+    // var i float32 = b   // compile-error: cannot use b (type nr) as type 
+    float32 in assignment
+    // var i = float32(b)  // compile-error: cannot convert b (type nr) to 
+    type float32
+    // var c number = b    // compile-error: cannot use b (type nr) as type number in assignment
+    // needs a conversion:
+    var c = number(b)
+    fmt.Println(a, b, c)
+}
+```
+
+输出:
+
+    {5} {5} {5}
+
+**练习**
+
+*练习 10.1* 
+
+vcard.go:定义结构体Address和VCard,后者包含一个人的名字、地址编号、出生日期和图像,试着选择正确的数据类型。构建一个自己的vcard并打印它的内容。
+
+提示:
+
+VCard必须包含住址,它应该以值类型还是以指针类型放在VCard中呢?
+
+第二种会好点,因为它占用内存少。包含一个名字和两个指向地址的指针的Address结构体可以使用%v打印:
+
+    {Kersschot 0x126d2b80 0x126d2be0} 
+
+*练习 10.2* 修改*persionext1.go*,使它的参数upPerson不是一个指针,解释下二者的区别。
+
+*练习 10.3* point.go:使用坐标X、Y定义一个二维Point结构体。同样地,对一个三维点使用它的极坐标定义一个Polar结构体。实现一个Abs()方法来计算一个Point表示的向量的长度,实现一个Scale方法,它将点的坐标乘以一个尺度因子(提示:使用math包里的Sqrt函数)( function Scale that multiplies the coordinates of a point with a scale 
+factor)
+
+*练习 10.3* rectangle.go:定义一个Rectangle结构体,它的长和宽是int类型,并定义方法Area()和Primeter()并测试
 
 ## 链接
 - [目录](directory.md)
 - 上一节:[10 结构(struct)与方法(method)](10.0.md)
-- 下一节:[regexp 包](09.2.md)
+- 下一节:[10.2 使用工厂方法创建结构体](10.2.md)

BIN
eBook/images/10.1_fig10.3.jpg


BIN
eBook/images/10.1_fig10.4.jpg