1. 定義
結構體是將另個或者多個任意類型的命名變數組合在一起的彙總資料類型。
2. 成員變數
- 存取控制機制
如果一個結構體的成員變數名稱是首字母大些的,那麼這個變數是可匯出的(即在其他包可以訪問到)。
一個結構體可以同時包含可匯出和不可匯出的成員變數
type A struct { Hour int //可匯出 minute int //不可匯出}
- 限制
命名結構體類型s不可以定義一個擁有相同結構體類型s的成員變數,也就是一個彙總類型不可以包含它自己。但是s中可以定義一個s的指標類型,即*s。如下:
type B struct { value int //Next B //錯誤 Next *B //正確}
3. 結構體比較
- 如果結構體的所有成員變數都可以比較,那麼這個結構體是可以比較的。兩個結構體的比較可以使用==或者!=。
type C struct { A int B string}c1 := C{A:1, B:"abc"}c2 := C{A:1, B:"abc"}c3 := C{A:2, B:"abc"}fmt.Println(c1.A == c2.A && c1.B == c2.B) //truefmt.Println(c1 == c2) //true 與上等價fmt.Println(c1.A == c3.A && c1.B == c3.B) //falsefmt.Println(c1 == c3) //false 與上等價
2.和其他可比較的類型一樣,可比較的結構體類型都可以作為map的鍵類型。
type C struct { A int B string}mp := make(map[C]int)key := C{A:1, B:"abc"}mp[key] = 9fmt.Println(mp[C{A:1, B:"abc"}]) //9
4. 結構體嵌套和匿名成員
- go允許我們定義不帶名稱的結構體成員,只需要指定類型即可;這種結構體成員稱作匿名成員。這個結構體成員的類型必須是一個命名類型或者指向命名類型的指標。正是因為有了這種結構體嵌套的功能,我們才能直接存取到我們需要的變數而不是指定一大串中間變數。
type Point struct { X int Y int}type Circle struct { Point}var c Circlec.X = 10 //等價於 c.Point.X = 10c.Y = 10 //等價於 c.Point.Y = 10type Wheel struct { *Point}
- 結構體字面量初始化沒有捷徑,必須遵循形狀類型的定義。
type Point struct { X int Y int}type Circle struct { Point}var c Circlec = Circle{1,1} //錯誤c = Circle{Point{1,1}} //正確c = Circle{Point: Point{1,1}} //正確
3.因為“匿名成員”擁有隱式的名字,所以你不能在一個結構體裡面定義兩個相同類型的匿名成員,否則會引起衝突。由於匿名成員的名字是由它們的類型決定的,因此它們的可匯出性也是由他們的的類型決定。在下面的例子中,point和circle這兩個匿名成員是可匯出的,即使這兩個結構體是不可匯出的(point和circle)。
type point struct { X int Y int}type circle struct { point}type Wheel struct { circle}var w Wheelw.X = 8 // 等價於 w.circle.point.X = 8, w.X是可匯出的,w.circle.point.X是不可匯出的