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
你能更详细地描述你的问题吗?
更多关于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 方法签名显示有两个返回值:*ChangeInfo 和 error,而你试图将其赋值给单个变量。因此不应这样写:
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.com、tour.golang.org
如果某个返回值对你无关紧要,你可以简单地用下划线变量(_)来丢弃它,这也被称为空白标识符blank identifier
你可以这样做:
_ , d := "Hello",5 // 如果你对 "Hello" 不感兴趣,只想丢弃它
但之后你将无法这样做:
fmt.Println(_, d)
但这会正常工作:
fmt.Println(d)
希望这能解释清楚。
错误出现在 c.Upsert(colQuerier, item) 这一行。mgo 的 Upsert 方法返回两个值:(info *ChangeInfo, err error),但你的代码只接收一个 err 变量。
在 Go 语言中,当一个函数返回多个值时,必须全部接收或明确忽略不需要的值。这里你需要处理 Upsert 返回的 *ChangeInfo 和 error。
修复方法有两种:
方法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 错误就会消失。

