从Win10到Linux交叉编译代码时,以下代码停止使用rows.next
executed rows.Next()
rows, err := DB.Query("SELECT * FROM `machines`")
erh.Check(err)
newUsers := make(map[string]User, count)
defer erh.Check(rows.Close())
for rows.Next() {
//tu is temp user
tu := User{}
err := rows.Scan(&tu.Id, &tu.Name, &tu.Apikey, &tu.Ip, &tu.Machine, &tu.State, &tu.DbAvailable)
erh.Check(err)
log.Println(tu)
newUsers[tu.Apikey] = tu
}
当我把defer放在行下面时。下一行。下一个代码执行
rows, err := DB.Query("SELECT * FROM `machines`")
erh.Check(err)
newUsers := make(map[string]User, count)
for rows.Next() {
//tu is temp user
tu := User{}
err := rows.Scan(&tu.Id, &tu.Name, &tu.Apikey, &tu.Ip, &tu.Machine, &tu.State, &tu.DbAvailable)
erh.Check(err)
log.Println(tu)
newUsers[tu.Apikey] = tu
}
defer erh.Check(rows.Close())
有人能确认这是一个bug吗,或者我在这里遗漏了什么?
我不确定这在Linux上如何工作,它不应该。此行:
defer erh.Check(rows.Close())
将立即执行rows.Close()
,保留返回值,然后仅延迟对erh.Check
的调用。这就是defer的工作原理——立即评估参数。来自文档:
每次执行"defer"语句时,函数值和调用的参数都会像往常一样求值并重新保存,但实际函数不会被调用。
如果你想使用这样的构造,它必须在闭包内,比如:
defer func() {
erh.Check(rows.Close())
}()
因此在defer
时没有要评估的自变量。