【发布时间】:2014-07-03 15:01:19
【问题描述】:
我正在查看代码示例sql.query,我对变量的初始化方式有点困惑。据我了解 var 关键字初始化变量,但如果您已经有这样的变量,最好“重用”它而不是重新初始化它。我知道我可能误解了 golang 规范,所以我希望这个问题能帮助我(也许还有其他人)做对。
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
为什么“name”变量是在循环内初始化而不是在循环外? (见下文)。在每个循环上重新初始化它的性能是否会降低?
//how I would do this
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
var name string //outside the loop
for rows.Next() {
if err := rows.Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
甚至更好地使用指针
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
name := new(string) //pointer outside the loop
for rows.Next() {
if err := rows.Scan(name); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
【问题讨论】:
-
name在循环之前声明,否则它将被限定为 if 块并且不在该块之外的范围内(阅读:之后不能使用它)。循环不会重新初始化它;它只是重复使用它。块(循环)在变量声明之后。 -
只想提一下
name实际上是在循环中声明的,而不是之前(在 sql 文档中)。在我看来,我错过了块范围的事情。我不知道if(也许还有for)块有这种隔离属性
标签: performance go