为了账号安全,请及时绑定邮箱和手机立即绑定

Go中切片的通用类型

Go中切片的通用类型

Go
慕尼黑5688855 2022-05-10 13:40:41
我不想拥有多个 API 获取函数,而是想创建一个函数来获取适当的数据库,将其格式化为一个结构切片,然后返回它。以下是我的代码的简化版本:type Person struct {        Name   string `json:"name"`        IsCool bool   `json:"is_cool"`}type Pet struct {        Name     string `json:"name"`        IsFluffy bool   `json:"is_fluffy"`}type Group struct {        Name         string    `json:"name"`        CreationDate time.Time `json:"creation_date"`}type generic interface{}func FetchDB(dbName string) interface {        var collection []generic        var model      generic        switch dbName {        case "users":                collection = new([]User)                model      = new(User)        }        case "pets":                collection = new([]Pet)                model      = new(Pet)        case "groups":                collection = new([]Group)                model      = new(Group)        default:                return nil        }        iter := client.DB(dbName).Get()        for {                entry, err := iter.Next()                if err != nil {                        break                }                entry.ToStruct(&model)                collection = append(collection, model)        }        return collection}但是,调用此函数会导致cannot use new([]User) (type *[]User) as type []generic in assignment. 我的第一个问题是如何创建“通用”切片并为其分配类型。我的第二个问题是,这是否是设置这个功能的正确方法——使用generic界面感觉很hacky!——如果不是,那么设计这个功能的更明智的方法是什么。
查看完整描述

1 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

您正在使用new,而不是make切片。这两个是不同的。new为类型分配内存(在这种情况下,是切片,而不是切片的内容),而make创建该类型的实例(make([]User,0) 将创建用户切片)。


您可以按如下方式进行这项工作:


collection:=make([]generic,0)

switch dbName {

   case "users":

       model      = new(User)

   case "pets":

       model      = new(Pet)

   case "groups":

       model      = new(Group)

   default:

       return nil

}

而且您model已经是一个指针,并且您希望将数据存储在该指针指向的位置:


  entry.ToStruct(model)  // Not &model

您正在返回一个interface{},而不是您可以 return []generic,这使您免于使用一种类型断言来获取值的数组部分。但这就是你的问题开始的时候,因为 Go 中没有泛型,你必须编写许多类型断言来获取你需要的数据。


有几种方法可以做到这一点。一种方法是收集数据的回调函数:


func FetchDB(dbName string, collector func(entry Entry) {

  iter := client.DB(dbName).Get()

  for {

        entry, err := iter.Next()

        collector(entry)

   }

}

并将其称为:


users:=make([]User,0)

FetchDB("users",func(entry Entry) {

   var u User

   entry.ToStruct(&u)

   users=append(users,u) 

 })


查看完整回答
反对 回复 2022-05-10
  • 1 回答
  • 0 关注
  • 203 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信