匿名欄位和內嵌結構體

2021-08-18 02:58:54 字數 1613 閱讀 9164

結構體可以包含乙個或多個 匿名(或內嵌)字段,即這些字段沒有顯式的名字,只有欄位的型別是必須的,此時型別就是欄位的名字。匿名字段本身可以是乙個結構體型別,即 結構體可以包含內嵌結構體。

可以粗略地將這個和物件導向語言中的繼承概念相比較,隨後將會看到它被用來模擬類似繼承的行為。go 語言中的繼承是通過內嵌或組合來實現的,所以可以說,在 go 語言中,相比較於繼承,組合更受青睞

考慮如下的程式:

package main

import

"fmt"

type inners struct

type outers struct

func main() }

fmt.println("outer2 is:", outer2)

}

輸出

outer.b is: 6

outer.c is: 7.500000

outer.int

is: 60

outer.in1 is: 5

outer.in2 is: 10

outer2 is:}

通過型別 outer.int 的名字來獲取儲存在匿名欄位中的資料,於是可以得出乙個結論:在乙個結構體中對於每一種資料型別只能有乙個匿名字段。

同樣地結構體也是一種資料型別,所以它也可以作為乙個匿名欄位來使用,如同上面例子中那樣。外層結構體通過 outer.in1 直接進入內層結構體的字段,內嵌結構體甚至可以來自其他包。內層結構體被簡單的插入或者內嵌進外層結構體。這個簡單的「繼承」機制提供了一種方式,使得可以從另外乙個或一些型別繼承部分或全部實現。

package main

import

"fmt"

type a struct

type b struct

func main() ,3.0,4.0}

fmt.println(b.ax, b.ay, b.bx, b.by)

fmt.println(b.a)

}

結果

1 2 3 4

當兩個字段擁有相同的名字(可能是繼承來的名字)時該怎麼辦呢?

外層名字會覆蓋內層名字(但是兩者的記憶體空間都保留),這提供了一種過載欄位或方法的方式;

如果相同的名字在同一級別出現了兩次,如果這個名字被程式使用了,將會引發乙個錯誤(不使用沒關係)。沒有辦法來解決這種問題引起的二義性,必須由程式設計師自己修正。

type

a struct

type

b struct

type

c struct

var c c;

規則 2:使用 c.a 是錯誤的,到底是 c.a.a 還是 c.b.a 呢?會導致編譯器錯誤:ambiguous dot reference c.a

type

d struct

var d d;

規則1:使用 d.b 是沒問題的:它是 float32,而不是 b 的 b。如果想要內層的 b 可以通過 d.b.b 得到。

6 7 Go語言內嵌結構體成員名字衝突

嵌入結構體內部可能擁有相同的成員名,成員重名時會發生什麼?下面通過例子來講解。package main import fmt type a struct type b struct type c struct func main c.a.a 1 fmt.println c 說明如下 第 7 行和第 ...

6 2 Go 匿名字段

golang匿名字段 可以像訪問字段成員那樣,訪問匿名字段方法,go編譯器自動查詢。package main import fmt type student struct type teacher struct func s1 student play func main 兩種方式一樣效果 t1 t...

golang 方法及struct的匿名字段方法繼承

go方法 一般的函式定義叫做函式 定義在結構提上面的函式叫做該結構體的方法 package main import fmt type rect struct 這個area方法有乙個限定型別 rect 表示這個函式是定義在rect結構體上的方法 func r rect area int 方法的定義限定...