golang中的匿名組合-創(chuàng)新互聯(lián)

確切地說,Go語言也提供了繼承,但是采用了組合的文法,所以我們將其稱為匿名組合:

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),點軍企業(yè)網(wǎng)站建設(shè),點軍品牌網(wǎng)站建設(shè),網(wǎng)站定制,點軍網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,點軍網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

type Base struct {

   Name string

}

func (base *Base) Foo() {...}

func (base *Base) Bar() {...}

type Foo struct {

   Base

   ...

}

func (foo *Foo) Bar() {

   foo.Base.Bar()

   ...

}

以上代碼定義了一個Base類(實現(xiàn)了Foo()和Bar()兩個成員方法),然后定義了一個Foo類,該類從Base類“繼承”并改寫了Bar()方法(該方法實現(xiàn)時先調(diào)用了基類的Bar()方法)。

在“派生類”Foo沒有寫“基類”Base的成員方法時,相應(yīng)的方法就被“繼承”,例如在上面的例子中,調(diào)用foo.Foo()和調(diào)用foo.Base.Foo()效果一致。

與其他語言不同,Go語言很清晰地告訴你的內(nèi)存布局是怎樣的。此外,在Go語言中你還可以隨心所欲地修改內(nèi)存布局,如:

type Foo struct {

   ...//其他成員

   Base

}

這段代碼從語義上來說,和上面的例子并無不同,但內(nèi)存布局發(fā)生了改變?!盎悺盉ase的數(shù)據(jù)放在了“派生類”Foo的最后。

另外,在Go語言中,你還可以以指針方式從一類類型“派生”:

type Foo struct {

   *Base

   ...

}

這段Go代碼仍然有“派生”的效果,只是Foo創(chuàng)建實例的時候,需要外部提供一個Base類實例的指針。

在C++語言中其實也有類似的功能,那就是虛基類,但是它非常讓人難以理解,一般C++的開發(fā)者都會遺忘這個特性。相比之下,Go語言以一種非常容易理解的方式提供了一些原本期望用虛基類才能解決的設(shè)計難題。

在Go語言官方網(wǎng)站提供的Effective Go中曾提到匿名組合的一個小價值,值得在這里再提一下。首先我們可以定義如下的類型,它匿名組合了一個log.logger指針:

type Job struct {

   Command string

   *log.Logger

}

在合適的賦值后,我們在Job類型的所有成員方法中可以很舒適地借用所有l(wèi)og.Logger提供的方法。比如如下的寫法:

func (job *Job) Start() {

   job.Log("starting now...")

   ...//做一些事情

   job.Log("started.")

}

對于Job的實現(xiàn)者來說,他甚至根本就不用意識到log.logger類型的存在,這就是匿名組合的魅力所在。在實際工作中,只有合理利用才能大發(fā)揮這個功能的價值。

需要注意的是,不管是非匿名的類型組合還是匿名組合,被組合的類型所包含的方法雖然都升級了外部這個組合類型的方法,但其實它們被組合的方法調(diào)用時接收者并沒有改變。比如上面這個Job例子,即使組合后調(diào)用的方式變成了job.Log(...),但Log函數(shù)的接收者仍然是log.Logger指針,因此在Log中不可能訪問到j(luò)ob的其他成員方法和變量。

這其實也很容易理解,畢竟被組合的類型并不知道自己會被什么類型組合,當然就沒法在實現(xiàn)方法時去使用那個未知的“組合者”的功能了。

另外,我們必須關(guān)注一下接口組合中的名字沖突問題,比如如下的組合:

type X struct {

   Name string

}

type Y struct {

   X

   Name string

}

組合的類型和被組合的類型都包含一個Name成員,會不會有問題呢?答案是否定的。所有的Y類型的Name成員的訪問都只會訪問到最外層的那個Name變量,X.Name變量相當于被隱藏起來了。

那么下面這樣的場景呢:

type Logger struct {

   level int

}

type Y struct {

   *Logger

   Name string

   *log.Logger

}

顯然這里會有問題。因為之前已經(jīng)提到過,匿名組合類型相當于以其類型名稱(去掉包名部分)作為成員變量的名字。按此規(guī)則,Y類型中就相當于存在兩個名為Logger的成員,雖然類型不同。因此,我們預(yù)期會收到編譯錯誤。

有意思的是,這個編譯錯誤并不是一定會發(fā)生的。假如這兩個Logger在定義后再也沒有被用過,那么編譯器將直接忽略掉這個沖突問題,直至開發(fā)者開始使用其中的某個Logger。

創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機房獨有T級流量清洗系統(tǒng)配攻擊溯源,準確進行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。

網(wǎng)站題目:golang中的匿名組合-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article8/dcjsip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃網(wǎng)站維護、搜索引擎優(yōu)化、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)站設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

小程序開發(fā)