回到简体

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. 結構體
## 4.4. 结构体
結構體是一聚合的數據類型,是由零或多任意型的值聚合成的實體。每個值稱爲結構體的成。用結構體的經典案例理公司的工信息,每個員工信息包含一唯一的員工編號、員工的名字、家庭住址、出生日期、工作位、薪、上級領導等等。所有的些信息都需要定到一個實體中,可以作爲一個整體單元被複製,作爲函數的參數或返值,或者是被存儲到數組中,等等。
结构体是一聚合的数据类型,是由零或多任意型的值聚合成的实体。每个值称为结构体的成。用结构体的经典案例理公司的工信息,每个员工信息包含一唯一的员工编号、员工的名字、家庭住址、出生日期、工作位、薪、上级领导等等。所有的些信息都需要定到一个实体中,可以作为一个整体单元被复制,作为函数的参数或返值,或者是被存储到数组中,等等。
下面兩個語句聲明了一叫Employee的命名的結構體類型,併且聲明了一Employee型的量dilbert
下面两个语句声明了一叫Employee的命名的结构体类型,并且声明了一Employee型的量dilbert
```Go
type Employee struct {
@@ -18,33 +18,33 @@ type Employee struct {
var dilbert Employee
```
dilbert結構體變量的成可以通過點操作符訪問比如dilbert.Name和dilbert.DoB。因dilbert是一個變量,它所有的成也同樣是變量,我可以直接對每個成員賦值:
dilbert结构体变量的成可以通过点操作符访问比如dilbert.Name和dilbert.DoB。因dilbert是一个变量,它所有的成也同样是变量,我可以直接对每个成员赋值:
```Go
dilbert.Salary -= 5000 // demoted, for writing too few lines of code
```
或者是對成員取地址,然後通過指針訪問
或者是对成员取地址,然后通过指针访问
```Go
position := &dilbert.Position
*position = "Senior " + *position // promoted, for outsourcing to Elbonia
```
操作符也可以和指向結構體的指一起工作:
操作符也可以和指向结构体的指一起工作:
```Go
var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"
```
當於下面
当于下面
```Go
(*employeeOfTheMonth).Position += " (proactive team player)"
```
下面的EmployeeByID函數將根據給定的工ID返迴對應的員工信息結構體的指。我可以使用操作符來訪問它里面的成
下面的EmployeeByID函数将根据给定的工ID返回对应的员工信息结构体的指。我可以使用操作符来访问它里面的成
```Go
func EmployeeByID(id int) *Employee { /* ... */ }
@@ -55,9 +55,9 @@ id := dilbert.ID
EmployeeByID(id).Salary = 0 // fired for... no real reason
```
面的句通EmployeeByID返迴的結構體指針更新了Employee結構體的成。如果EmployeeByID函的返迴值從`*Employee`針類型改Employee值型,那更新語句將不能編譯通過,因爲在賦值語句的左邊併不確定是一個變量(譯註:調用函數返迴的是值,不是一可取地址的量)。
面的句通EmployeeByID返回的结构体指针更新了Employee结构体的成。如果EmployeeByID函的返回值从`*Employee`针类型改Employee值型,那更新语句将不能编译通过,因为在赋值语句的左边并不确定是一个变量(译注:调用函数返回的是值,不是一可取地址的量)。
通常一行對應一個結構體成員,成的名字在前型在,不如果相的成員類型如果相同的可以被合到一行就像下面的Name和Address成員那樣
通常一行对应一个结构体成员,成的名字在前型在,不如果相的成员类型如果相同的可以被合到一行就像下面的Name和Address成员那样
```Go
type Employee struct {
@@ -70,13 +70,13 @@ type Employee struct {
}
```
結構體成員的輸入順序也有重要的意。我也可以Position成員合併(因也是字符串型),或者是交Name和Address出的先後順序,那樣的話就是定了不同的結構體類型。通常,我們隻是將相關的成員寫到一起。
结构体成员的输入顺序也有重要的意。我也可以Position成员合并(因也是字符串型),或者是交Name和Address出的先后顺序,那样的话就是定了不同的结构体类型。通常,我们只是将相关的成员写到一起。
如果結構體成員名字是以大字母開頭的,那麽該成員就是出的;是Go語言導出規則決定的。一個結構體可能同包含出和未出的成
如果结构体成员名字是以大字母开头的,那么该成员就是出的;是Go语言导出规则决定的。一个结构体可能同包含出和未出的成
結構體類型往往是冗的,因它的每個成員可能都占一行。然我每次都可以重寫整個結構體成員,但是重複會令人厭煩。因此,完整的結構體寫法通常隻在類型聲明語句的地方出就像Employee類型聲明語句那
结构体类型往往是冗的,因它的每个成员可能都占一行。然我每次都可以重写整个结构体成员,但是重复会令人厌烦。因此,完整的结构体写法通常只在类型声明语句的地方出就像Employee类型声明语句那
命名S的結構體類型將不能再包含S型的成:因爲一個聚合的值不能包含它自身。(該限製同樣適應於數組但是S型的結構體可以包含`*S`針類型的成員,這可以讓我們創建遞歸的數據結構,比如表和樹結構等。在下面的代中,我使用一二叉樹來實現一個插入排序:
命名S的结构体类型将不能再包含S型的成:因为一个聚合的值不能包含它自身。(该限制同样适应于数组但是S型的结构体可以包含`*S`针类型的成员,这可以让我们创建递归的数据结构,比如表和树结构等。在下面的代中,我使用一二叉树来实现一个插入排序:
<u><i>gopl.io/ch4/treesort</i></u>
```Go
@@ -121,9 +121,9 @@ func add(t *tree, value int) *tree {
}
```
結構體類型的零值是每個成員都對是零值。通常會將零值作最合理的默值。例如,對於bytes.Buffer型,結構體初始值就是一個隨時可用的空存,有在第9章將會講到的sync.Mutex的零值也是有效的未鎖定狀態。有時候這種零值可用的特性是自然得的,但是也有些型需要一些外的工作。
结构体类型的零值是每个成员都对是零值。通常会将零值作最合理的默值。例如,对于bytes.Buffer型,结构体初始值就是一个随时可用的空存,有在第9章将会讲到的sync.Mutex的零值也是有效的未锁定状态。有时候这种零值可用的特性是自然得的,但是也有些型需要一些外的工作。
如果結構體沒有任何成員的話就是空結構體,寫作struct{}。它的大小0也不包含任何信息但是有候依然是有值的。有些Go言程序用map帶模擬set數據結構時,用它代替map中布爾類型的value隻是強調key的重要性但是因爲節約的空有限,而且法比較複雜,所有我通常避免避免這樣的用法。
如果结构体没有任何成员的话就是空结构体,写作struct{}。它的大小0也不包含任何信息但是有候依然是有值的。有些Go言程序用map带模拟set数据结构时,用它代替map中布尔类型的value只是强调key的重要性但是因为节约的空有限,而且法比较复杂,所有我通常避免避免这样的用法。
```Go
seen := make(map[string]struct{}) // set of strings