<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
先看如下程式碼:
type user struct { name string email string } type admin struct { user // Embedded Type level string }
可以看到admin結構中的一個成員是user,那麼admin中就嵌入了user型別。
func (u *user) notify() { fmt.Printf("Sending user email to %s<%s>n", u.name, u.email) }
如上程式碼,實現了一個方法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函數中定義了一個變數ad,並且進行了賦值
執行:
Sending user email to john smith<john@yahoo.com>
Sending user email to john smith<john@yahoo.com>
①沒有編譯錯誤
②notify()可以被ad.user呼叫是可以理解的,但是ad.notify()也能執行是為什麼。
這裡涉及到了一個嵌入型別背後的機制,內部型別提升 (感覺有點像C#、Java裡面的繼承,user是父類別,admin是子類,admin的範例物件直接呼叫了父類別的notify方法。)
進一步研究:我們再定義一個介面、以及一個接受該介面的函數。
介面,只有一個方法notify
type notifier interface { notify() }
函數,接受一個實現notifier介面的型別範例,內部就是呼叫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) }
執行結果:
Sending user email to john smith<john@yahoo.com>
Sending user email to john smith<john@yahoo.com>
①可以看到這裡傳入 &user和&ad都是可以的,說明型別提升導致admin也是實現了notifier介面了。
②為什麼穿&user和&ad,而不是直接傳user和ad,這就涉及到了之前總結過的【方法集】的概念了。複習一下:
從上面兩個表,可以知道由於方法的接收者是 *user ,所以說只有*user實現了該介面的方法,這就是為什麼輸入&user、&ad了
再進一步研究:我們在C#當中,如果使用了virtual作為修飾符在父類別中寫了一個方法,那麼在子類中通過override可以重寫這個方法,最終的結果就是呼叫的非父類別的該方法,而是子類的,Go語言同樣可以。
例如
// 通過admin 型別值的指標 // 呼叫的方法 func (a *admin) notify() { fmt.Printf("Sending admin email to %s<%s>n", a.name, a.email) }
在剛剛的程式碼中,追加一個*admin作為接受者的方法。
執行結果如下:
Sending user email to john smith<john@yahoo.com>
Sending admin email to john smith<john@yahoo.com>
可以發現此時這兩此執行的結果就不一樣了,第二次sendNotification(&ad)呼叫的notify方法就是admin這個型別的了。
這表明,如果外部型別實現了notify 方法,內部型別的實現就不會被提升。不過內部型別的值一直存在,因此還可以通過直接存取內部型別的值,來呼叫沒有被提升的內部型別實現的方法。
綜上:嵌入型別為Go語言型別提供了一種很好的擴充套件能力,通過內部型別的提升,使得外部型別擁有了內部型別的方法,也可以通過外部型別實現同樣的方法來替代內部型別的。總體來說很像C#語言中的繼承。
到此這篇關於Go語言之嵌入型別的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45