回到简体

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,8 +1,8 @@
### 4.4.3. 結構體嵌入和匿名成
### 4.4.3. 结构体嵌入和匿名成
在本中,我們將看到如何使用Go言提供的不同常的結構體嵌入機製讓一個命名的結構體包含另一個結構體類型的匿名成員,這樣就可以通過簡單的點運算符x.f來訪問匿名成員鏈中嵌套的x.d.e.f成
在本中,我们将看到如何使用Go言提供的不同常的结构体嵌入机制让一个命名的结构体包含另一个结构体类型的匿名成员,这样就可以通过简单的点运算符x.f来访问匿名成员链中嵌套的x.d.e.f成
慮一個二維的繪圖程序,提供了一個各種圖形的,例如矩形、橢圓形、星形和形等何形狀。這里是其中兩個的定
虑一个二维的绘图程序,提供了一个各种图形的,例如矩形、椭圆形、星形和形等何形状。这里是其中两个的定
```Go
type Circle struct {
@@ -14,7 +14,7 @@ type Wheel struct {
}
```
Circle代表的圓形類型包含了標準圓心的X和Y坐信息,和一Radius表示的半信息。一Wheel形除了包含Circle型所有的全部成外,增加了Spokes表示徑向輻條的數量。我可以這樣創建一wheel量:
Circle代表的圆形类型包含了标准圆心的X和Y坐信息,和一Radius表示的半信息。一Wheel形除了包含Circle型所有的全部成外,增加了Spokes表示径向辐条的数量。我可以这样创建一wheel量:
```Go
var w Wheel
@@ -24,7 +24,7 @@ w.Radius = 5
w.Spokes = 20
```
隨着庫中幾何形狀數量的增多,我一定會註意到它們之間的相似和重複之處,所以我可能了便於維護而將相同的屬性獨立出
随着库中几何形状数量的增多,我一定会注意到它们之间的相似和重复之处,所以我可能了便于维护而将相同的属性独立出
```Go
type Point struct {
@@ -42,7 +42,7 @@ type Wheel struct {
}
```
這樣改動之後結構體類型變的清晰了,但是這種脩改同時也導致了訪問每個成員變得繁
这样改动之后结构体类型变的清晰了,但是这种修改同时也导致了访问每个成员变得繁
```Go
var w Wheel
@@ -52,7 +52,7 @@ w.Circle.Radius = 5
w.Spokes = 20
```
Go言有一特性讓我們隻聲明一個成員對應的數據類型而不指名成的名字;這類成員就叫匿名成。匿名成員的數據類型必是命名的型或指向一命名的型的指。下面的代Circle和Wheel各自都有一匿名成。我可以Point型被嵌入到了Circle結構體,同Circle型被嵌入到了Wheel結構體
Go言有一特性让我们只声明一个成员对应的数据类型而不指名成的名字;这类成员就叫匿名成。匿名成员的数据类型必是命名的型或指向一命名的型的指。下面的代Circle和Wheel各自都有一匿名成。我可以Point型被嵌入到了Circle结构体,同Circle型被嵌入到了Wheel结构体
```Go
type Circle struct {
@@ -66,7 +66,7 @@ type Wheel struct {
}
```
得意匿名嵌入的特性,我可以直接訪問葉子屬性而不需要出完整的路
得意匿名嵌入的特性,我可以直接访问叶子属性而不需要出完整的路
```Go
var w Wheel
@@ -76,16 +76,16 @@ w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20
```
在右邊的註釋中給出的式形式訪問這些葉子成員的語法依然有效,因此匿名成員併不是眞的無法訪問了。其中匿名成Circle和Point都有自己的名字——就是命名的型名字——但是些名字在操作符中是可的。我們在訪問子成員的時候可以忽略任何匿名成部分。
在右边的注释中给出的式形式访问这些叶子成员的语法依然有效,因此匿名成员并不是真的无法访问了。其中匿名成Circle和Point都有自己的名字——就是命名的型名字——但是些名字在操作符中是可的。我们在访问子成员的时候可以忽略任何匿名成部分。
不幸的是,結構體字面值併沒有簡短表示匿名成員的語法, 因此下面的句都不能編譯通過
不幸的是,结构体字面值并没有简短表示匿名成员的语法, 因此下面的句都不能编译通过
```Go
w = Wheel{8, 8, 5, 20} // compile error: unknown fields
w = Wheel{X: 8, Y: 8, Radius: 5, Spokes: 20} // compile error: unknown fields
```
結構體字面值必遵循形狀類型聲明時的結構,所以我們隻能用下面的兩種語法,它彼此是等的:
结构体字面值必遵循形状类型声明时的结构,所以我们只能用下面的两种语法,它彼此是等的:
<u><i>gopl.io/ch4/embed</i></u>
```Go
@@ -110,16 +110,16 @@ fmt.Printf("%#v\n", w)
// Wheel{Circle:Circle{Point:Point{X:42, Y:8}, Radius:5}, Spokes:20}
```
需要意的是Printf函中%v參數包含的#副它表示用和Go語言類似的法打印值。對於結構體類型來説,將包含每個成員的名字。
需要意的是Printf函中%v参数包含的#副它表示用和Go语言类似的法打印值。对于结构体类型来说,将包含每个成员的名字。
匿名成也有一個隱式的名字,因此不能同包含兩個類型相同的匿名成員,這會導致名字突。同,因爲成員的名字是由其類型隱式地定的,所有匿名成也有可性的規則約束。在上面的例子中Point和Circle匿名成都是出的。使它們不導出(比如改成小字母開頭的point和circle依然可以用短形式訪問匿名成嵌套的成
匿名成也有一个隐式的名字,因此不能同包含两个类型相同的匿名成员,这会导致名字突。同,因为成员的名字是由其类型隐式地定的,所有匿名成也有可性的规则约束。在上面的例子中Point和Circle匿名成都是出的。使它们不导出(比如改成小字母开头的point和circle依然可以用短形式访问匿名成嵌套的成
```Go
w.X = 8 // equivalent to w.circle.point.X = 8
```
但是在包外部,因circle和point沒有導出不能訪問它們的成,因此短的匿名成員訪問語法也是禁止的。
但是在包外部,因circle和point没有导出不能访问它们的成,因此短的匿名成员访问语法也是禁止的。
到目前止,我看到匿名成特性隻是對訪問嵌套成員的點運算符提供了短的法糖。稍,我們將會看到匿名成員併不要求是結構體類型;其任何命名的型都可以作爲結構體的匿名成。但是爲什麽要嵌入一個沒有任何子成員類型的匿名成員類型呢?
到目前止,我看到匿名成特性只是对访问嵌套成员的点运算符提供了短的法糖。稍,我们将会看到匿名成员并不要求是结构体类型;其任何命名的型都可以作为结构体的匿名成。但是为什么要嵌入一个没有任何子成员类型的匿名成员类型呢?
答案是匿名型的方法集。短的點運算符法可以用於選擇匿名成嵌套的成,也可以用於訪問它們的方法。實際上,外層的結構體不僅僅是獲得了匿名成員類型的所有成,而且也得了該類型導出的全部的方法。這個機製可以用於將一個有簡單行爲的對象組合成有複雜行爲的對象。合是Go言中面向對象編程的核心,我們將在6.3節中專門討論
答案是匿名型的方法集。短的点运算符法可以用于选择匿名成嵌套的成,也可以用于访问它们的方法。实际上,外层的结构体不仅仅是获得了匿名成员类型的所有成,而且也得了该类型导出的全部的方法。这个机制可以用于将一个有简单行为的对象组合成有复杂行为的对象。合是Go言中面向对象编程的核心,我们将在6.3节中专门讨论