我正在查看代码示例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)
}
为什么“名称”变量在循环内初始化并且不在循环之外? (见下文)。在每个循环中重新初始化它不是没有那么高效吗?
//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块并且不在该块之外的范围内(阅读:以后不能使用它)。循环不会重新初始化它;它只是重新使用它。块(循环)位于变量声明之后。 – elithrar
只是想提一下''name''实际上是在循环之内声明的(在sql文档中)。在我看来,我错过了块范围的东西。我不知道''if''(也可能是''for'')块具有这种隔离属性 – hey
@hey:它包含在[The Go Programming Language Specification](http://golang.org/ref/spec):[Blocks](http://golang.org/ref/spec#Blocks)。 – peterSO