go - Go中 slice 的通用类型

标签 go

这个问题在这里已经有了答案:





Type converting slices of interfaces

(8 个回答)



What is the difference between new and make?

(3 个回答)


昨天关门了。




我不想拥有多个 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 .我的第一个问题是如何创建“通用” slice 并为其分配类型。我的第二个问题是这是否是设置此功能的正确方法 - 使用 generic界面感觉很hacky!-如果不是,那么设计此功能的更明智的方法是什么。

最佳答案

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

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

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{} , 而您可以返回 []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) 
 })

关于go - Go中 slice 的通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59902662/

相关文章:

go - 如何从 exec 命令获取错误消息

go - Go SDK使用的Gcloud身份验证帐户

go - 并行和顺序执行之间的闭包不一致

go - 如何覆盖 DefaultHTTPErrorHandler 格式消息

google-app-engine - 将字符串数据转换为在 Go AppEngine 上读取的结构 : Inserted on Java AppEngine (Objectify),

go - 反向代理是否可能将http/1.1连接升级到http2?

sql - 从SQL响应读取uniqueidentifier问题

docker 检查 : how to select only certain keys from range

go - Aerospike Go Client : No available connections to the node. 连接池为空,限制连接数

go - 将数组解码为结构