github 直达 github.com/daodao97/ggm
欢迎大佬们多多指点, 给个 Star.
包含泛型特性的 go1.18
已经正式发布, 于是就迫不及待的体验了一把.
我们来看下日常的 db
交互中, 使用泛型, 将会带来哪些便利.
以下为伪代码, 仅做示意.
// 预定义的结构体
type User struct{
Id int `db:"id"`
Name string `db:"name"`
}
database/sql
的原生写法db := sql.Open()
stmt, err := db.Prepare(sql)
if err != nil {
return
}
rows, err := stmt.Query(args...)
if err != nil {
return
}
var list []*User
for rows.Next() {
tmp := new(User)
rows.Scan(tmp.Id, tmp.User)
list = append(list, tmp)
}
原生写法相对比较繁琐, 可能一般项目中不会作为首选方案.
db = xxx.Conn()
var list []*User
_ = db.Query(sql, &list)
for _, u := range list {
fmt.Println(u.Id)
}
可以看出, 相对于原生写法, 代码已经十分简洁, 但是我们不得不提前定义 var list []*User
并且需要将其已指针形式 &list
传入类库, 熟悉其他语言的同学就会觉得这里看起来十分蹩脚了.
list, _ := ggm.New[User]().Select(sql)
for _, u := range list {
fmt.Println(u.Id)
}
在泛型类库中, 查询后, 无需任何转换 list
的类型已经是 []User
.
相对于第二写种法, 代码又精进了异步, 更加的简洁直观了.
github 直达 github.com/daodao97/ggm
欢迎大佬们多多指点, 给个 Star.
1
GeruzoniAnsasu 2022-03-19 04:33:02 +08:00 1
…… 无恶意,你看过 GORM 的源码吗
当执行一个查询的时候,model 一定是「有类型」的,所以在设计查询接口的时候,目标并不是抹除输入数据的类型差异,相反还要要提取出输入的类型特征加以处理。所以 gorm 用 interface{}来接纳任意类型后用了大量反射手段去还原 interface 的具体 <模型或类型> 是啥 之前看过有个大佬写的博客感觉很有启发,泛型能改善的最大问题是高阶函数: func (S) filter (d []type1, f func (e type1) bool ) []type1 和 func (S) filter (d []type2, f func (e type2) bool ) []type2 是两个不同的函数。但有了泛型,可以只写一次。 https://go.dev/play/p/OHdhzMstFxW 我感觉 拼一套低配 LINQ 还是挺有可能而且有意义的 |
2
kaichen 2022-03-19 09:20:28 +08:00
|
3
bthulu 2022-03-19 10:44:34 +08:00
不要泛型, 泛型是异端, 统统烧死
|
4
wenjie0032 OP @GeruzoniAnsasu 赞同大佬的观点, 泛型确实会对工具类函数很有帮助, 能显著的减少代码量, 比如 2 楼大佬贴的 lo 库,
ggm 内部也会用反射去解析下当前 struct 的属性, 并未看过 gorm 的源码, 私以为跟 sqlx 类的 底层原理应该是相似的. 此处也只是泛型出来后的上手实践, 玩玩儿嘛 |
5
wenjie0032 OP @bthulu 新鲜事物还是要接受一下的, 哈哈
|
6
raaaaaar 2022-03-19 14:34:42 +08:00 via Android
尴尬了,我的 stl 库看来这下要大改了
|
7
wwaayyaa 2022-03-22 15:39:04 +08:00
@GeruzoniAnsasu 赞同,其实这次泛型出来了,我最兴奋的就是我可以更快的撸业务了。
所以写了一个包,各位大佬可以看看。 https://v2ex.com/t/842117 https://github.com/wwaayyaa/go-collection |