您好,登錄后才能下訂單哦!
今天小編給大家分享一下Go語(yǔ)言之嵌入類型是什么的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。
先看如下代碼:
type user struct { name string email string } type admin struct { user // Embedded Type level string }
可以看到admin結(jié)構(gòu)中的一個(gè)成員是user,那么admin中就嵌入了user類型。
admin也叫做外部類型
user也叫做內(nèi)部類型
func (u *user) notify() { fmt.Printf("Sending user email to %s<%s>\n", u.name, u.email) }
如上代碼,實(shí)現(xiàn)了一個(gè)方法notify(),接收者是 *user。
func main() { // Create an admin user. ad := admin{ user: user{ name: "john smith", email: "john@yahoo.com", }, level: "super", } // We can access the inner type's method directly. ad.user.notify() // The inner type's method is promoted. ad.notify() }
main函數(shù)中定義了一個(gè)變量ad,并且進(jìn)行了賦值
運(yùn)行:
Sending user email to john smith<john@yahoo.com>
Sending user email to john smith<john@yahoo.com>
①?zèng)]有編譯錯(cuò)誤
②notify()可以被ad.user調(diào)用是可以理解的,但是ad.notify()也能執(zhí)行是為什么。
這里涉及到了一個(gè)嵌入類型背后的機(jī)制,內(nèi)部類型提升 (感覺有點(diǎn)像C#、Java里面的繼承,user是父類,admin是子類,admin的實(shí)例對(duì)象直接調(diào)用了父類的notify方法。)
進(jìn)一步研究:我們?cè)俣x一個(gè)接口、以及一個(gè)接受該接口的函數(shù)。
接口,只有一個(gè)方法notify
type notifier interface { notify() }
函數(shù),接受一個(gè)實(shí)現(xiàn)notifier接口的類型實(shí)例,內(nèi)部就是調(diào)用notify方法
func sendNotification(n notifier) { n.notify() }
main方法如下
func main() { // Create an admin user. ad := admin{ user: user{ name: "john smith", email: "john@yahoo.com", }, level: "super", } var user = ad.user sendNotification(&user) sendNotification(&ad) }
運(yùn)行結(jié)果:
Sending user email to john smith<john@yahoo.com>
Sending user email to john smith<john@yahoo.com>
①可以看到這里傳入 &user和&ad都是可以的,說(shuō)明類型提升導(dǎo)致admin也是實(shí)現(xiàn)了notifier接口了。
②為什么穿&user和&ad,而不是直接傳user和ad,這就涉及到了之前總結(jié)過的【方法集】的概念了。復(fù)習(xí)一下:
從上面兩個(gè)表,可以知道由于方法的接收者是 *user ,所以說(shuō)只有*user實(shí)現(xiàn)了該接口的方法,這就是為什么輸入&user、&ad了
再進(jìn)一步研究:我們?cè)贑#當(dāng)中,如果使用了virtual作為修飾符在父類中寫了一個(gè)方法,那么在子類中通過override可以重寫這個(gè)方法,最終的結(jié)果就是調(diào)用的非父類的該方法,而是子類的,Go語(yǔ)言同樣可以。
例如
// 通過admin 類型值的指針 // 調(diào)用的方法 func (a *admin) notify() { fmt.Printf("Sending admin email to %s<%s>\n", a.name, a.email) }
在剛剛的代碼中,追加一個(gè)*admin作為接受者的方法。
運(yùn)行結(jié)果如下:
Sending user email to john smith<john@yahoo.com>
Sending admin email to john smith<john@yahoo.com>
可以發(fā)現(xiàn)此時(shí)這兩此運(yùn)行的結(jié)果就不一樣了,第二次sendNotification(&ad)調(diào)用的notify方法就是admin這個(gè)類型的了。
這表明,如果外部類型實(shí)現(xiàn)了notify 方法,內(nèi)部類型的實(shí)現(xiàn)就不會(huì)被提升。不過內(nèi)部類型的值一直存在,因此還可以通過直接訪問內(nèi)部類型的值,來(lái)調(diào)用沒有被提升的內(nèi)部類型實(shí)現(xiàn)的方法。
以上就是“Go語(yǔ)言之嵌入類型是什么”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。