用一个数据处理库来泛型尝鲜

2022-04-24 21:09:47 +08:00
 jdlau

这是一个用 Go 实现的数据处理库,升级之前用 interface{}表示参数类型,阅读起来还是容易模糊。现在泛型出了之后,就把它升级一下:

原来:

// extract column from table
// * First Argument:table
// * Second Argument:column name
result := query.Column(users, "UserID")
userIDs := result.([]int)

// generate a map from table,key is column value and value is it's row
// * First Argument:table
// * Second Argument:column name
result = query.ColumnMap(users, "UserID")
userMap := result.(map[int]User)

// select data from table
// * First Argument:table
// * Second Argument:select rule
result = query.Select(users, func(a User) Sex {
    if len(a.Name) >= 3 && a.Name[0:3] == "Man" {
        return Sex{IsMale: true}
    }
    return Sex{IsMale: false}
})
sel := result.([]Sex)

// filter data from table
// * First Argument:table
// * Second Argument:filter rule
result = query.Where(users, func(a User) bool {
    if len(a.Name) >= 3 && a.Name[0:3] == "Man" {
        return true
    }
    return false
})
where := result.([]User)

// group data from table
// * First Argument: left table
// * Second Argument: group column name
// * Third Argument: group rule
result = query.Group(users, "UserID", func(users []User) Department {
    return Department{
        Employees: users,
    }
})
group := result.([]Department)

// join data from two table ,support LeftJoin,RightJoin,InnerJoin 和 OuterJoin
// * First Argument: left table
// * Second Argument: right table
// * Third Argument: join condition
// * Forth Argument: join rule
result = query.LeftJoin(admins, users, "AdminID = UserID", func(admin Admin, user User) AdminUser {
    return AdminUser{
        AdminID:    admin.AdminID,
        Level:      admin.Level,
        Name:       user.Name,
        CreateTime: user.CreateTime,
    }
})
join := result.([]AdminUser)

现在

// extract column from table
// * First Argument:table
// * Second Argument:column name
userIDs := query.Column[User, int](users, "UserID") // []int

// generate a map from table,key is column value and value is it's row
// * First Argument:table
// * Second Argument:column name
userMap = query.ColumnMap[User, int, map[int]User](users, "UserID") // map[int]User
// or
usersMap = query.ColumnMap[User, int, map[int][]User](users, "[]UserID") // map[int][]User

// select data from table
// * First Argument:table
// * Second Argument:select rule
sel = query.Select(users, func(a User) Sex {
    if len(a.Name) >= 3 && a.Name[0:3] == "Man" {
        return Sex{IsMale: true}
    }
    return Sex{IsMale: false}
}) // []Sex

// filter data from table
// * First Argument:table
// * Second Argument:filter rule
where = query.Where(users, func(a User) bool {
    if len(a.Name) >= 3 && a.Name[0:3] == "Man" {
        return true
    }
    return false
}) // []User

// group data from table
// * First Argument: left table
// * Second Argument: group column name
// * Third Argument: group rule
group = query.Group[User, Department, []Department](users, "UserID", func(users []User) Department {
    return Department{
        Employees: users,
    }
}) // []Department
// or
group = query.Group[User, []Department, *[]Department](users, "UserID", func(users []User) []Department {
    return []Department{
        Employees: users,
    }
}) // *[]Department

// join data from two table ,support LeftJoin,RightJoin,InnerJoin 和 OuterJoin
// * First Argument: left table
// * Second Argument: right table
// * Third Argument: join condition
// * Forth Argument: join rule
join = query.LeftJoin(admins, users, "AdminID = UserID", func(admin Admin, user User) AdminUser {
    return AdminUser{
        AdminID:    admin.AdminID,
        Level:      admin.Level,
        Name:       user.Name,
        CreateTime: user.CreateTime,
    }
}) // []AdminUser

减少了断言,还是挺好的。

一点问题

目前的 Go 泛型不支持类型参数内嵌,所以在 Group 函数里使用了指针。

// 这样是不行的
func Group[T, E any, R E | []E](data []T, groupType string, groupFunctor func([]T) E) R
// 只好写成这样
func Group[T, E any, R *E | []E](data []T, groupType string, groupFunctor func([]T) E) R 
1508 次点击
所在节点    Go 编程语言
2 条回复
seakingii
2022-04-25 16:43:34 +08:00
GO 的泛型语法真奇葩
jdlau
2022-04-25 17:01:22 +08:00
@seakingii 各花入各眼。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/849010

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX