3 回答

TA貢獻1830條經驗 獲得超3個贊
因為可以有多個具有相同名稱的變量,只要它們具有不同的作用域即可。內部作用域中的變量將遮蔽外部作用域中的變量。
因此,如果我們分解您的示例
func badQueue() {
// queue from outer scope, lets call it A
queue := []int{0,1,2,3,4,5}
// the only visible queue here is A, so len(queue) will always refer to A
for len(queue) > 0 {
// same thing here, the only visible queue is A, so queue[0] and queue[1:]
// both refer to A
// We are also declaring new variables, queue and current
// This queue is now shadowing the outer queue, let's call this one B
current, queue := queue[0], queue[1:]
// Here queue will refer to B
fmt.Println(current, queue)
// When the current iteration of the loop ends current and queue B is destroyed
// because they go out of scope and the loop start over with A unchanged
}
}

TA貢獻1818條經驗 獲得超7個贊
要了解它在 Go 中的工作原理,需要兩點:
范圍
Go 使用塊作用域,每個大括號對將創建一個新作用域,如果內部作用域中的標識符具有相同的聲明名稱,則它們將隱藏外部作用域中的標識符。
func main() {
var name string = "Golang"
fmt.Printf("Outer Scope: %s\n", name) // Print "Golang"
{
var name string = "Java"
fmt.Printf("Inner Scope: %s\n", name) // Print "Java"
}
fmt.Printf("Outer Scope: %s\n", name) // Print "Golang" again
}
短變量聲明
Operator是一個復合操作,它將在一個語句中做幾件事:聲明,類型推斷和賦值,基本上你可以把它當作一個語法糖。以下 S1 和 S2 的代碼示例是等效的::=
func main() {
// S1
var name string = "Golang"
// S2
name := "Golang"
}
考慮到以上兩點,您的代碼在翻譯后將如下所示:
func badQueue() {
queue := []int{0,1,2,3,4,5}
for len(queue) > 0 {
var current int
var queue []int
current, queue = queue[0], queue[1:]
fmt.Println(current, queue)
}
}
很明顯,外部不受影響內部循環。queuefor
順便說一句,對于左側的每個變量,編譯器將查找當前塊范圍以嘗試解析標識符,如果之前已經聲明過,編譯器將重用它而不是創建一個新的。但是,如果之前聲明了所有 lhs 變量,編譯器將報告一個錯誤,并顯示消息“:=的左側沒有新變量”。請查看以下代碼::=
func main() {
var name string
name, age := "Golang", 10 // reuse the above 'name' and create a new variable 'age'
var tom, jerry string
tom, jerry := "Tom", "Jerry" // no new variables on left side of :=
}
新的編譯器實現在這里,適合那些對細節感興趣的人。
- 3 回答
- 0 關注
- 119 瀏覽
添加回答
舉報