而不是具有多个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
界面感觉很糟糕!),如果不是,那么设计此功能的更明智的方法是什么。
您正在使用new
,而不是make
用于切片。那两个是不同的。 new
为该类型分配内存(在这种情况下,为切片,而不是切片的内容),而make
为该类型创建实例(make([] User,0)将为Users的切片) 。
您可以按照以下步骤进行这项工作:
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)
})