我正在查看代碼示例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