網站首頁 編程語言 正文
1. 泛型是什么
泛型生命周期只在編譯期,旨在為程序員生成代碼,減少重復代碼的編寫
在比較兩個數的大小時,沒有泛型的時候,僅僅只是傳入類型不一樣,我們就要再寫一份一模一樣的函數,如果有了泛型就可以減少這類代碼
// int func GetMaxNumInt(a, b int) int { if a > b { return a } return b } // int8 func GetMaxNumInt8(a, b int8) int8 { if a > b { return a } return b }
2. 泛型的簡單使用
2.1. 泛型示例
需要go版本大于等于1.18
我們先改造一下上面的示例,只需要在函數后用中括號聲明T可能出現的類型,中間用符號"|" 分隔
// 使用泛型 func GetMaxNum[T int | int8](a, b T) T { if a > b { return a } return b }
2.2. 自定義泛型類型
如果類型太多了怎么辦呢?這時候我們就可以自定義泛型類型
// 像聲明接口一樣聲明 type MyInt interface { int | int8 | int16 | int32 | int64 } // T的類型為聲明的MyInt func GetMaxNum[T MyInt](a, b T) T { if a > b { return a } return b }
2.3. 調用帶泛型的函數
如何調用這個帶有泛型的函數呢?
var a int = 10 var b int = 20 // 方法1,正常調用,編譯器會自動推斷出傳入類型是int GetMaxNum(a, b) // 方法2,顯式告訴函數傳入的類型是int GetMaxNum[int](a, b)
3. 自定義泛型類型的語法
在2.2小節中我們可以看到一個泛型的簡單自定義類型,本節將會詳細描述泛型自定義類型的語法
3.1. 內置的泛型類型any和comparable
any: 表示go里面所有的內置基本類型,等價于interface{}
comparable: 表示go里面所有內置的可比較類型:int、uint、float、bool、struct、指針等一切可以比較的類型
3.2. 聲明一個自定義類型
跟聲明接口一樣,使用type x interface{} 關鍵字來聲明,不過里面的成員不再是方法,而是類型,類型之間用符號 "|" 隔開
type MyInt interface { int | int8 | int16 | int32 | int64 }
成員類型支持go中所有的基本類型
type MyT interface { int | float32 | bool | chan int | map[int]int | [10]int | []int | struct{} | *http.Client }
3.3. 泛型中的"~"符號是什么
符號"~"都是與類型一起出現的,用來表示支持該類型的衍生類型
// int8的衍生類型 type int8A int8 type int8B = int8 // 不僅支持int8, 還支持int8的衍生類型int8A和int8B type MyInt interface { ~int8 }
4. 泛型的進階使用
4.1. 泛型與結構體
創建一個帶有泛型的結構體User,提供兩個獲取age和name的方法
注意:只有在結構體上聲明了泛型,結構體方法中才可以使用泛型
type AgeT interface { int8 | int16 } type NameE interface { string } type User[T AgeT, E NameE] struct { age T name E } // 獲取age func (u *User[T, E]) GetAge() T { return u.age } // 獲取name func (u *User[T, E]) GetName() E { return u.name }
我們可以通過聲明結構體對象時,聲明泛型的類型來使用帶有泛型的結構體
// 聲明要使用的泛型的類型 var u User[int8, string] // 賦值 u.age = 18 u.name = "weiwei" // 調用方法 age := u.GetAge() name := u.GetName() // 輸出結果 18 weiwei fmt.Println(age, name)
5. 泛型的限制或缺陷
5.1 無法直接和switch配合使用
將泛型和switch配合使用時,無法通過編譯
func Get[T any]() T { var t T switch T { case int: t = 18 } return t }
只能先將泛型賦值給interface才可以和switch配合使用
func Get[T any]() T { var t T var ti interface{} = &t switch v := ti.(type) { case *int: *v = 18 } return t }
原文鏈接:https://blog.csdn.net/qq_42062052/article/details/123840525
相關推薦
- 2023-04-06 Python求字符串的長度示例代碼_python
- 2022-09-24 C#中ref關鍵字的用法_C#教程
- 2022-10-08 LyScript實現繞過反調試保護的示例詳解_python
- 2022-07-11 go語言實現二叉樹的序例化與反序列化_Golang
- 2022-06-09 ASP.NET?Core中的Configuration配置一_基礎應用
- 2023-12-09 添加依賴時,出現了此問題maven Cannot resolve org.apache.dubbo:
- 2022-05-18 C語言?動態內存開辟常見問題解決與分析流程_C 語言
- 2022-01-18 報錯:Error occurred when invoke the listener‘s inter
- 最近更新
-
- 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同步修改后的遠程分支