【Golang】1.18泛型初步理解
796 字
4 分钟
【Golang】1.18泛型初步理解

0x00
这次golang正式更新了泛型(之前的1.17 和1.18 Beta 1 中的只是测试版,其中有一些用法和正式版有较大的差别),是一次重大的更新,原以为在GO2.0的时候更新。
0x01 类型形参(Type Parameters)
在之前想要实现一些通用的功能还是比较麻烦的,而且代码冗余。
比如实现gorm添加json类型字段:
type Table struct { AField A BField B}
type A struct { AText string}func (A) GormDataType() string { return "json"}func (a *A) Scan(value interface{}) error { return json.Unmarshal(value.([]byte), a)}func (a A) Value() (value driver.Value, err error) { src, err := json.Marshal(a) return string(src), err}
type B struct { BText string}func (B) GormDataType() string { return "json"}func (b *B) Scan(value interface{}) error { return json.Unmarshal(value.([]byte), b)}func (b B) Value() (value driver.Value, err error) { src, err := json.Marshal(b) return string(src), err}可以看到A和B中的GormDataType Scan Value方法几乎都是重复的,假如再添加C D那么就要添加6个重复发方法。
而golang 1.8开始正式支持泛型,那么利用泛型可以降低这样的代码冗余
使用泛型再次实现上述内容:
type Table struct { AField JSON[A] BField JSON[B]}
type A struct { AText string}
type B struct { BText string}
type JSON[T any] struct { Data T}func (JSON[T]) GormDataType() string { return "json"}func (m *JSON[T]) Scan(value interface{}) error { return json.Unmarshal(value.([]byte), &m.Data)}func (m JSON[T]) Value() (value driver.Value, err error) { src, err := json.Marshal(m.Data) return string(src), err}可以看到我这里定义了一个JSON[T any]的类型专门处理json类型,此后添加C D字段就只需要定义相关的结构体并且添加JSON[C] JSON[D]即可。
其中any类型也是这次更新后的新类型字段,但any其实就是interface类型的别称
源码:
// src/builtin/builtin.go 95行
// any is an alias for interface{} and is equivalent to interface{} in all ways.type any = interface{}个人感觉any相比interface在传参等场合更直观
比如:
func Println(v ...any){}
func Println(v ...interface){}当然,在定义接口时还是得用interface字段
判断类型
func (m *JSON[T]) Test() { switch any(m.Data).(type) { case A: fmt.Println("A") case B: fmt.Println("B") }}0x02 类型集合(Type Sets)
类型集合允许定义一个类型具有不同类型的集合
例如:
type Test interface { int|float64}定义了一个Test类型,表示为int float64类型的集合
如果不用泛型那怎么写呢
不使用泛型:
func Add(a, b interface{}) interface{} { switch a.(type) { case int: return a.(int)+b.(int) case float64: return a.(float64)+b.(float64) } return 0}使用泛型:
func Add[T int | float64](a, b T) T { return a + b}这样一对比使用泛型就简洁多了
应用:
type Num interface { int | int64 | int32 | float64 | float32 | uint | uint8 | uint16 | uint64}
func Add[T Num](a, b T) T { return a + b}
func Sub[T Num](a, b T) T { return a - b}0x03 类型约束
type T interface { int | float64 | ~string}其中的~string表示定义的T类型集合也支持底层类型是string的类型
比如:
type A interface { ~string}
func Splic[T A](a, b T) T { return a + b}
var BString string
func main() { var a string = "a" var b BString = "b"
Splic(a, b)}其中BString是自定义的一个底层为string的类型,如果没有加~的话会报错
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!
相关文章智能推荐
1
【Golang】GO项目结构
Golang笔记2019-06-25
2
【Golang】使用CGO交叉编译
Golang笔记2020-04-08
3
【Golang】命令行传递参数
Golang笔记2018-09-13
4
【Golang】关于time包的一些记录
Golang笔记2022-01-04
5
【Golang】调用syscall调用windows dll弹窗
Golang笔记2022-09-22
随机文章随机推荐















加载更多…