寫在前面
疊代變量的使用,在立即執行的函數中,一般是不會顯現問題的,但是在延遲執行的函數中,就會出現緻命的問題。
立即執行的情況
當然,這種例子有很多,這裡舉一個非常簡單的例子分析一下。場景需求:将silce内的數字疊代輸出即可。
package main
import "fmt"
func main() {
var numsSilces []int
for i:=0; i<10; i++ {
numsSilces = append(numsSilces, i)
}
for _, num := range numsSilces {
fmt.Println(num)
}
}
這樣的程式運作無任何問題,輸出0-9
延遲執行的情況
一般說到延遲運作,在Go語言中,使用較多的是defer這個關鍵字,這裡主要是以較為特殊的例子進行說明。代碼見下:
package main
/**
主要涉及到go語言中的疊代變量的捕獲
*/
import "fmt"
func main() {
var handles []func()
var numsSilces []int
for i:=0; i<10; i++ {
numsSilces = append(numsSilces, i)
}
for _, num := range numsSilces {
handles = append(handles, func() {
fmt.Println(num)
})
}
for _, handle := range handles {
handle()
}
}
輸出結果均為9。其實看到輸出結果,也基本可以推斷出程式運作的過程了,這裡的疊代變量num,其并非指向的是一個固定的值,其指向的是一個可通路的存儲位置,每一次疊代的過程,都是将疊代的獲得值寫入到了這個固定的存儲位置中。存儲位置不變,但存儲的值會伴随着疊代的次數進行更新,是以最終num的值全部指向的是9。
問題解決
出現這種問題時,一般是采用引入一個内部變量,并利用疊代變量進行初始化的方式,對每一次疊代的值進行儲存。如下:
package main
/**
主要涉及到go語言中的疊代變量的捕獲
*/
import "fmt"
func main() {
var handles []func()
var numsSilces []int
for i:=0; i<10; i++ {
numsSilces = append(numsSilces, i)
}
for _, num := range numsSilces {
num := num //引入内部變量對值進行儲存,并采用疊代變量的值進行初始化
handles = append(handles, func() {
fmt.Println(num)
})
}
for _, handle := range handles {
handle()
}
}
感覺這種坑是自己以後可能會遇到的,是以還是提前記錄一下。