在 BSON 中解码,一个由私有结构实现的接口
Decode in BSON, an interface which is implemented by a private structure
我正在尝试用 Go 做一个基本的 TODO 列表应用程序。我正在从 mongodb atlas 在我的集群上创建 CRUD 操作。但是我在解码 BSON 对象时遇到问题。对于我的模型,我使用了一个未导入的结构,但它实现了一个在回购中使用的接口。尝试从数据库中读取时出现此错误:
panic: no decoder found for interfaces.IToDoItem
我知道我应该以某种方式为我的界面实现一个解码器,但无法实现,如果不从模型中导出我的主要结构。这也意味着我在模型中没有隐私,模型中的项目可以在程序的任何模式下访问,我认为这是错误的。
这是我的代码:
model.go
type toDoItem struct{
ItemId int `bson:"itemId,omitempty"`
Title string `bson:"title,omitempty"`
Description string `bson:"description,omitempty"`
}
func New(itemId int,title string,description string) interfaces.IToDoItem {
return toDoItem{
ItemId: itemId,
Title: title,
Description: description,
}
}
func (item toDoItem)GetItemId()int{
return item.ItemId
}
func (item toDoItem)GetTitle()string{
return item.Title
}
func (item toDoItem)GetDescription()string{
return item.Description
}
界面
type IToDoItem interface {
GetItemId() int
GetTitle() string
GetDescription() string
}
回购函数
func (r *Repository)GetAll() []interfaces.IToDoItem{
cursor, err := r.collection.Find(context.TODO(), bson.D{})
if err != nil{
panic(err)
}
defer cursor.Close(context.Background())
var allItems []interfaces.IToDoItem
for cursor.Next(context.Background()){
var result interfaces.IToDoItem
err := cursor.Decode(&result)
if err!= nil{
panic(err)
}
allItems = append(allItems[:],result)
}
fmt.Println(allItems)
return []interfaces.IToDoItem{}
}
现在它return 什么都没有,因为我想在 repo 级别解决问题。
接口不是具体类型,可能有多种(任意数量)类型实现它。驱动程序理所当然地不知道如何实例化它。
toDoItem
的字段已导出,没有理由不导出 toDoItem
本身。只需导出它并使用一片 []ToDoItem
(或 []*ToDoItem
),所有问题都会消失。
另请注意,每个都有一个 Cursor.All()
method to get all results, so you don't have to iterate over the documents and call Cursor.Decode()
。
如果您需要注册自定义解码器,请查看此答案:
我正在尝试用 Go 做一个基本的 TODO 列表应用程序。我正在从 mongodb atlas 在我的集群上创建 CRUD 操作。但是我在解码 BSON 对象时遇到问题。对于我的模型,我使用了一个未导入的结构,但它实现了一个在回购中使用的接口。尝试从数据库中读取时出现此错误:
panic: no decoder found for interfaces.IToDoItem
我知道我应该以某种方式为我的界面实现一个解码器,但无法实现,如果不从模型中导出我的主要结构。这也意味着我在模型中没有隐私,模型中的项目可以在程序的任何模式下访问,我认为这是错误的。
这是我的代码:
model.go
type toDoItem struct{
ItemId int `bson:"itemId,omitempty"`
Title string `bson:"title,omitempty"`
Description string `bson:"description,omitempty"`
}
func New(itemId int,title string,description string) interfaces.IToDoItem {
return toDoItem{
ItemId: itemId,
Title: title,
Description: description,
}
}
func (item toDoItem)GetItemId()int{
return item.ItemId
}
func (item toDoItem)GetTitle()string{
return item.Title
}
func (item toDoItem)GetDescription()string{
return item.Description
}
界面
type IToDoItem interface {
GetItemId() int
GetTitle() string
GetDescription() string
}
回购函数
func (r *Repository)GetAll() []interfaces.IToDoItem{
cursor, err := r.collection.Find(context.TODO(), bson.D{})
if err != nil{
panic(err)
}
defer cursor.Close(context.Background())
var allItems []interfaces.IToDoItem
for cursor.Next(context.Background()){
var result interfaces.IToDoItem
err := cursor.Decode(&result)
if err!= nil{
panic(err)
}
allItems = append(allItems[:],result)
}
fmt.Println(allItems)
return []interfaces.IToDoItem{}
}
现在它return 什么都没有,因为我想在 repo 级别解决问题。
接口不是具体类型,可能有多种(任意数量)类型实现它。驱动程序理所当然地不知道如何实例化它。
toDoItem
的字段已导出,没有理由不导出 toDoItem
本身。只需导出它并使用一片 []ToDoItem
(或 []*ToDoItem
),所有问题都会消失。
另请注意,每个都有一个 Cursor.All()
method to get all results, so you don't have to iterate over the documents and call Cursor.Decode()
。
如果您需要注册自定义解码器,请查看此答案: