泛型实战

此开源图书由ithaiq原创,创作不易转载请注明出处

1. 打印字符串

func printStr[T any](str []T) {
	for _, v := range str {
		fmt.Println(v)
	}
}
var str = []string{"test1", "test2"}
var val = []int{1, 2}
printStr(str)                                 
printStr(val)  

2. 构造方法

type Model[T1 any, T2 any] struct {
	val T1
	str T2
}

//构造方法
func NewModel[T1 any, T2 any](val T1, str T2) *Model[T1, T2] {
	return &Model[T1, T2]{val: val, str: str}
}
fmt.Println(NewModel[int, string](12, "34").str)

3. 工厂模式

//工厂模式
type Book struct {
	Pid int
}

func (b *Book) SetId(val int) {
	b.Pid = val
}

type TV struct {
	Pid string
}
type Man struct {
	Age int
}

func (m *Man) SetId(val int) {
	m.Age = val
}

type Obj interface {
	Book | Man
}

func CreateFactory[T Obj]() *T {
	var obj T
	return &obj
}

type Ptr[T any] interface {
	*T
	SetId(val int)
}

func CreateFactory2[T Ptr[U], U Obj]() T {
	var obj U
	//T(&obj).SetId(2)
	return T(&obj)
}

CreateFactory[Book]()
CreateFactory[Man]()
//CreateFactory[TV]() //TV does not implement Obj
fmt.Println(CreateFactory[Book]().Pid)            //这里goland显示Pid有问题无法定位索引所以有下面第二种写法
fmt.Println(CreateFactory2[*Book, Book]().Pid)    //2

4. json反序列化

//json反序列化
var strJson = `{"name":"ithaiq"}`
var strListJson = `[{"name":"ithaiq"}]`

func Decode(str string) interface{} {
	var data interface{}
	err := json.Unmarshal([]byte(str), &data)
	if err != nil {
		panic(err)
	}
	return data
}

type DecodeType interface {
	map[string]interface{} | interface{}
}

func Decode2[T DecodeType](str string) T {
	var data T
	err := json.Unmarshal([]byte(str), &data)
	if err != nil {
		panic(err)
	}
	return data
}
fmt.Println(Decode(strListJson))                              //map[string]interface{} []interface{}
fmt.Println(Decode2[map[string]interface{}](strJson)["name"]) //ithaiq

5. Gorm封装

type DbModel struct {
	Id   int64
	Name string
}

func main() {
	db, err := gorm.Open(mysql.Open("root:root@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{
		Logger: logger.Default.LogMode(logger.Info),
	})
	if err != nil {
		panic(err)
	}
	//var data DbModel
	//err = db.Where("id = ?", 1).Find(&data).Error
	//if err != nil {
	//	panic(err)
	//}
	//fmt.Println(data)
	var data DbModel
	dbHandler := NewDBHandler[*DbModel](db)
	dbHandler.Get(context.Background(), &data)
	fmt.Println(data)
	var data2 DbModel
	dbHandler.Get2(context.Background(), &data2, GetOptions{FieldSelector: map[string]interface{}{
		"id =?": 10,
	}})
	fmt.Println(data2)
	var data3 []*DbModel
	dbHandler.List(context.Background(), &data3, ListOptions{
		FieldSelector: map[string]interface{}{
			"id > ?": 1,
		},
		Limit: 10,
	})
}

type DBHandler[T any] struct {
	db *gorm.DB
}

type GetOptions struct {
	FieldSelector map[string]interface{}
}
type ListOptions struct {
	FieldSelector map[string]interface{}
	Limit         int
	Offset        int
	OrderBy       string
}

func NewDBHandler[T any](db *gorm.DB) *DBHandler[T] {
	return &DBHandler[T]{db: db}
}

func (d *DBHandler[T]) Get(ctx context.Context, data T) error {
	return d.db.Where("id = ?", 1).Find(&data).Error
}

func (d *DBHandler[T]) Get2(ctx context.Context, data T, ops GetOptions) error {
	db := d.db
	if ops.FieldSelector != nil {
		for k, v := range ops.FieldSelector {
			db = db.Where(k, v)
		}
	}
	return db.Find(&data).Error
}

func (d *DBHandler[T]) List(ctx context.Context, data *[]T, ops ListOptions) error {
	db := d.db
	if ops.FieldSelector != nil {
		for k, v := range ops.FieldSelector {
			db = db.Where(k, v)
		}
	}
	if ops.Limit != 0 {
		db = db.Limit(ops.Limit)
	}
	if ops.Offset != 0 {
		db = db.Offset(ops.Offset)
	}
	if ops.OrderBy != "" {
		db = db.Order(ops.OrderBy)
	}
	return db.Find(&data).Error
}

最后更新于

这有帮助吗?