Go語言之嵌入型別

2021-09-20 20:37:39 字數 2692 閱讀 3751

嵌入型別,或者巢狀型別,這是一種可以把已有的型別宣告在新的型別裡的一種方式,這種功能對**復用非常重要。

在其他語言中,有繼承可以做同樣的事情,但是在go語言中,沒有繼承的概念。go提倡的**復用的方式是組合,所以這也是嵌入型別的意義所在。組合而不是繼承,所以go才會更靈活。

type reader inte***ce 

type writer inte***ce 

type closer inte***ce 

type readwriter inte***ce 

type readcloser inte***ce 

type writecloser inte***ce

以上是標準庫io包裡我們常用的介面,可以看到readwriter介面是嵌入readerreader介面而組合成的新介面,這樣我們就不用重複地定義被嵌入介面裡的方法,直接通過嵌入就可以了。嵌入型別同樣適用於結構體型別,我們再來看個例子:

type user struct 

type admin struct

嵌入後,被嵌入的型別稱之為內部型別,新定義的型別稱之為外部型別。這裡user就是內部型別,而admin是外部型別。

通過嵌入型別,與內部型別相關聯的所有字段、方法、標誌符等,都會被外包型別所擁有。就像外部型別自己的一樣,這就達到了**快捷復用組合的目的,而且定義非常簡單,只需宣告這個型別的名字就可以了。

同時,外部型別還可以新增自己的方法、字段屬性等,可以很方便地擴充套件外部型別的功能。

func main() ,"管理員"}

fmt.println("可以直接呼叫,名字為:",ad.name)

fmt.println("也可以通過內部型別呼叫,名字為:",ad.user.name)

fmt.println("但是新增加的屬性只能直接呼叫,級別為:",ad.level)

}

以上是嵌入型別的使用。可以看到,我們在初始化的時候,採用的是字面值的方式。所以要按其定義的結構進行初始化,先初始化user這個內部型別的,再初始化新增的level屬性。

對於內部型別的屬性和方法訪問,我們可以用外部型別直接訪問,也可以通過內部型別進行訪問;但是我們為外部型別新增的方法屬性字段,只能使用外部型別訪問,因為內部型別沒有這些。

當然,外部型別也可以宣告同名的字段或者方法,來覆蓋內部型別的,這種情況方法比較多,我們以方法為例。

func main() ,"管理員"}

ad.user.sayhello()

ad.sayhello()

}type user struct 

type admin struct 

func (u user) sayhello()

func (a admin) sayhello()

內部型別user有乙個sayhello方法,外部型別對其進行了覆蓋,同名重寫sayhello,然後我們在main方法裡分別訪問這兩個型別的方法,列印輸出:

hello,i am a user

hello,i am a admin

從輸出中看,方法sayhello被成功覆蓋了。

嵌入型別的強大,還體現在:如果內部型別實現了某個介面,那麼外部型別也被認為實現了這個介面。我們稍微改造下例子看下。

func main() ,"管理員"}

sayhello(ad.user)//使用user作為引數

sayhello(ad)//使用admin作為引數

}type hello inte***ce 

func (u user) hello()

func sayhello(h hello)

這個例子原來的結構體型別useradmin的定義不變,新增了乙個介面hello,然後讓user型別實現這個介面,最後我們定義了乙個sayhello方法,它接受乙個hello介面型別的引數。最終我們在main函式演示的時候,發現不管是user型別,還是admin型別作為引數傳遞給sayhello方法的時候,都可以正常呼叫。

這裡就可以說明admin實現了介面hello。但是我們又沒有顯示宣告型別admin實現,所以這個實現是通過內部型別user實現的;因為admin包含了user所有的方法函式,所以也就實現了介面hello

當然外部型別也可以重新實現,只需要像上面例子一樣覆蓋同名的方法即可。這裡要說明的是,不管我們如何同名覆蓋,都不會影響內部型別,我們還可以通過訪問內部型別來訪問它的方法、屬性欄位等。

嵌入型別的定義,是go為了方便我們擴充套件或者修改已有型別的行為,是為了宣傳組合這個概念而設計的,所以我們經常使用組合,靈活運用組合,擴充套件出更多的我們需要的型別結構

Go語言之Go 語言型別別名

在 go 1.9 版本之前定義內建型別的 是這樣寫的 type byte uint8 type rune int32而在 go 1.9 版本之後變為 type byte uint8 type rune int32 這個修改就是配合型別別名而進行的修改。定義型別別名的寫法 type typealias...

Go語言之GO 語言常量

相對於變數,常量是恆定不變的值,多用於定義程式執行期間不會改變的那些值。常量的宣告和變數宣告非常類似,只是把var換成了const,常量在定義的時候必須賦值。const pi 3.1415 const e 2.7182宣告了pi和e這兩個常量之後,在整個程式執行期間它們的值都不能再發生變化了。多個常...

Go語言之Go語言網路程式設計

go語言的 net 包中有乙個 tcpconn 型別,可以用來建立 tcp 客戶端和 tcp 伺服器端間的通訊通道,tcpconn 型別裡有兩個主要的函式 func c tcpconn write b byte n int,err os.error func c tcpconn read b byt...