網站首頁 編程語言 正文
一、什么是嵌入類型
先看如下代碼:
type user struct { name string email string } type admin struct { user // Embedded Type level string }
可以看到admin結構中的一個成員是user,那么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#語言中的繼承。
原文鏈接:https://www.cnblogs.com/dcz2015/p/10103443.html
相關推薦
- 2022-08-07 Android?實現自定義折線圖控件_Android
- 2022-08-01 OpenCV連通域數量統計學習示例_python
- 2023-02-12 Golang反射模塊reflect使用方式示例詳解_Golang
- 2022-08-29 詳解C語言中二級指針與鏈表的應用_C 語言
- 2022-06-29 詳解Shell腳本中^M的問題和解決方案_linux shell
- 2022-05-12 tp5使用阿里云oss存儲圖片
- 2022-09-26 Pytorch模型訓練和模型驗證
- 2022-10-15 C++?accumulate函數詳細介紹和具體案例_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支