Шаг Decode следующего кода неправильно заполняет исходный объект document. Он перезаписывает его объектом bson.

func main() {
    c := Call{}
    dbGetObject("collection", &c)
}

func dbGetObject(collectionName string, document interface{}) (err error) {
    uri, creds, auth := dbGetAuth()

    clientOpts := options.Client().ApplyURI(uri).SetAuth(creds)
    client, err := mongo.Connect(context.TODO(), clientOpts)
    if err != nil {
        log.Fatal(err)
        return err
    }
    defer client.Disconnect(context.TODO())

    collection := client.Database(auth.Database).Collection(collectionName)

    err = collection.FindOne(context.TODO(), bson.M{"number": "12345"}).Decode(&document)
    if err != nil {
        log.Fatal(err)
        return err
    }

    return nil
}

Тем не менее, следующий код работает правильно:

func dbGetObject(collectionName string) (err error) {
    uri, creds, auth := dbGetAuth()

    clientOpts := options.Client().ApplyURI(uri).SetAuth(creds)
    client, err := mongo.Connect(context.TODO(), clientOpts)
    if err != nil {
        log.Fatal(err)
        return err
    }
    defer client.Disconnect(context.TODO())

    collection := client.Database(auth.Database).Collection(collectionName)

    c := Call{}
    err = collection.FindOne(context.TODO(), bson.M{"number": "12345"}).Decode(&c)
    if err != nil {
        log.Fatal(err)
        return err
    }

    return nil
}

Единственная разница в том, что экземпляр структуры передается в функцию vs, созданную в функции dbGetObject. Что я делаю не так?

0
jimox 13 Ноя 2020 в 04:28

2 ответа

Лучший ответ

Я действительно понял, что происходит. При вызове функции и затем при декодировании я передаю указатель. Таким образом, он фактически передает указатель на указатель в вызов Decode. Итак, исправление состоит в том, чтобы изменить вызов декодирования с:

err = collection.FindOne(context.TODO(), bson.M{"number": "12345"}).Decode(&document)

К

err = collection.FindOne(context.TODO(), bson.M{"number": "12345"}).Decode(document)
0
jimox 13 Ноя 2020 в 03:41

В первом примере тип документа - interface. если вы исправите тип аргумента, как показано ниже, он будет работать правильно.

func dbGetObject(collectionName string, document *Call)
0
Jihoon Yeo 13 Ноя 2020 в 02:59