Golang中Goinsta和mgo代码错误排查与修复

Golang中Goinsta和mgo代码错误排查与修复 我在使用 item.ID 时遇到了 multiple-value c.Upsert() in single-value context 错误

我的代码如下:

package main

import (
	"fmt"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	e "gopkg.in/ahmdrz/goinsta.v2/examples"
)

func main() {
	session, err := mgo.Dial("127.0.0.1")
	if err != nil {
		panic(err)
	}
	defer session.Close()
	session.SetMode(mgo.Monotonic, true)
	c := session.DB("tanzen").C("monitoring")
	inst, err := e.InitGoinsta("")
	e.CheckErr(err)
	media := inst.Timeline.Get()
	for i := 0; i < 500; i++ {
		media.Next()
		fmt.Println("Next:", media.NextID)
		for _, item := range media.Items {
			fmt.Printf("%+v\n", item.User.FullName)
			colQuerier := bson.M{"id": item.ID}
			err = c.Upsert(colQuerier, item)
			if err != nil {
				panic(err)
			}
		}
	}
	if !e.UsingSession {
		err = inst.Logout()
		e.CheckErr(err)
	}
}

这是我第一次使用 Golang,谢谢


更多关于Golang中Goinsta和mgo代码错误排查与修复的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

你能更详细地描述你的问题吗?

更多关于Golang中Goinsta和mgo代码错误排查与修复的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


swinggame:

colQuerier := bson.M{"id": item.ID}
err = c.Upsert(colQuerier, item)

我对这部分感到困惑。

虽然在一个项目中支持过 mgo 但用得不多,查阅文档后发现集合的 Upsert 方法签名显示有两个返回值:*ChangeInfoerror,而你试图将其赋值给单个变量。因此不应这样写:

err = c.Upsert(colQuerier, item)

如果不需要处理 ChangeInfo 指针,应该这样写:

_, err = c.Upsert(colQuerier, item)

或者这样写以便后续使用 ci

ci, err := c.Upsert(colQuerier, item)

你好 @swinggame

@iegomez 解释得很好。

在 Go 语言中,函数或方法可以返回多个值,当它们这样做时,你必须用多个变量来接收,不能将两个不同的值存储在单个变量中。也就是说,如果你有一个字符串和一个整数值,你需要两个变量,一个存储字符串值,另一个存储整数值。

c, d := "Hello",5    // 将字符串值 "Hello" 赋给变量 c,整数值 5 赋给 d
fmt.Println(c, d)    // 将输出 - Hello 5

你不能这样做:

d := "Hello",5 // Go 语言不知道应该将哪些值赋给变量 d

请参考一些返回多个值的函数示例,通过实践来更好地理解,一些链接:gobyexample.comtour.golang.org

如果某个返回值对你无关紧要,你可以简单地用下划线变量(_)来丢弃它,这也被称为空白标识符blank identifier

你可以这样做:

_ , d := "Hello",5 // 如果你对 "Hello" 不感兴趣,只想丢弃它

但之后你将无法这样做:

fmt.Println(_, d)

但这会正常工作:

fmt.Println(d)

希望这能解释清楚。

错误出现在 c.Upsert(colQuerier, item) 这一行。mgoUpsert 方法返回两个值:(info *ChangeInfo, err error),但你的代码只接收一个 err 变量。

在 Go 语言中,当一个函数返回多个值时,必须全部接收或明确忽略不需要的值。这里你需要处理 Upsert 返回的 *ChangeInfoerror

修复方法有两种:

方法1:忽略不需要的返回值

_, err = c.Upsert(colQuerier, item)
if err != nil {
    panic(err)
}

方法2:接收所有返回值

changeInfo, err := c.Upsert(colQuerier, item)
if err != nil {
    panic(err)
}
// 如果需要可以使用 changeInfo
fmt.Printf("Upserted: %+v\n", changeInfo)

完整的修复代码:

package main

import (
	"fmt"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	e "gopkg.in/ahmdrz/goinsta.v2/examples"
)

func main() {
	session, err := mgo.Dial("127.0.0.1")
	if err != nil {
		panic(err)
	}
	defer session.Close()
	session.SetMode(mgo.Monotonic, true)
	c := session.DB("tanzen").C("monitoring")
	inst, err := e.InitGoinsta("")
	e.CheckErr(err)
	media := inst.Timeline.Get()
	for i := 0; i < 500; i++ {
		media.Next()
		fmt.Println("Next:", media.NextID)
		for _, item := range media.Items {
			fmt.Printf("%+v\n", item.User.FullName)
			colQuerier := bson.M{"id": item.ID}
			_, err = c.Upsert(colQuerier, item)  // 使用下划线忽略 ChangeInfo
			if err != nil {
				panic(err)
			}
		}
	}
	if !e.UsingSession {
		err = inst.Logout()
		e.CheckErr(err)
	}
}

这样修改后,multiple-value c.Upsert() in single-value context 错误就会消失。

回到顶部