Понимание типов интерфейсов в моделях mgo
В контексте MongoDB и Go моделирование данных с помощью интерфейсов может представлять проблемы из-за динамического характера интерфейсов. Вот краткое объяснение проблемы, с которой вы столкнулись, и предлагаемое решение.
Проблема с типами интерфейсов
Документная модель данных MongoDB не предоставляет тип информация для встроенных документов. При использовании mgo для демаршалинга документов MongoDB, содержащих типы интерфейсов, в структуры Go, mgo не может определить конкретный тип каждого встроенного документа. Это приводит к ошибке «значение типа bson.M не может быть назначено типу Node». заключается в том, чтобы обернуть тип интерфейса в специальную структуру, предоставляющую информацию о типе. Это позволяет mgo идентифицировать конкретный тип встроенного документа во время демаршаллинга.
Рассмотрим следующий пример:
type NodeWithType struct { Узел `bson:"-"` Введите строку } тип Структура рабочего процесса { СозданоВремя.Время Начато во время.Время Строка CreatedBy Узлы []NodeWithType }Реализация функции SetBSON
type NodeWithType struct {
Node Node `bson:"-"`
Type string
}
type Workflow struct {
CreatedAt time.Time
StartedAt time.Time
CreatedBy string
Nodes []NodeWithType
}
func (nt *NodeWithType) SetBSON(r bson.Raw) error { // Декодируем поле «Тип» и определяем тип узла строка var typeStr если ошибка := r.Unmarshal(&typeStr); ошибка != ноль { вернуть ошибку } // Создаем новый экземпляр типа Node на основе строки типа узел, ок:= Reflect.New(reflect.TypeOf(Node).Elem()).Interface().(Node) если !ок { вернуть ошибки.Новый("неверный тип узла") } // Демаршалируем оставшиеся данные в экземпляр Node если ошибка := r.Unmarshal(node); ошибка != ноль { вернуть ошибку } // Назначаем экземпляр Node структуре NodeWithType nt.Node = узел вернуть ноль }
Заключение
func (nt *NodeWithType) SetBSON(r bson.Raw) error {
// Decode the "Type" field and determine the Node type
var typeStr string
if err := r.Unmarshal(&typeStr); err != nil {
return err
}
// Create a new instance of the Node type based on the type string
node, ok := reflect.New(reflect.TypeOf(Node).Elem()).Interface().(Node)
if !ok {
return errors.New("invalid Node type")
}
// Unmarshal the remaining data into the Node instance
if err := r.Unmarshal(node); err != nil {
return err
}
// Assign the Node instance to the NodeWithType struct
nt.Node = node
return nil
}
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3