前言
在Golang中使用 for range 語句進行迭代非常的便捷,但在涉及到指針時就得小心一點了。
下面的代碼中定義了一個元素類型為 *int 的通道 ch :
package main
import (
"fmt"
)
func main() {
ch := make(chan *int, 5)
//sender
input := []int{1,2,3,4,5}
go func(){
for _, v := range input {
ch - v
}
close(ch)
}()
//receiver
for v := range ch {
fmt.Println(*v)
}
}
在上面代碼中,發(fā)送方將 input 數(shù)組發(fā)送給 ch 通道,接收方再從 ch 通道中接收數(shù)據(jù),程序的預(yù)期輸出應(yīng)該是:
現(xiàn)在運行一下程序,得到的輸出如下:
很明顯,程序并沒有達到預(yù)期的結(jié)果,那么問題出在哪里呢?我們將代碼稍作修改:
//receiver
for v := range ch {
fmt.Println(v)
}
得到如下輸出:
0x416020
0x416020
0x416020
0x416020
0x416020
可以看到,5次輸出變量 v ( *int )都指向了同一個地址,返回去檢查一下發(fā)送部分代碼:
for _, v := range input {
ch - v
}
問題正是出在這里,在 for range 語句中, v 變量用于保存迭代 input 數(shù)組所得的值,但是 v 只被聲明了一次,此后都是將迭代 input 出的值賦值給 v , v 變量的內(nèi)存地址始終未變,這樣再將 v 的地址發(fā)送給 ch 通道,發(fā)送的都是同一個地址,當然無法達到預(yù)期效果。
解決方案:
引入一個中間變量,每次迭代都重新聲明一個變量 temp ,賦值后再將其地址發(fā)送給 ch :
for _, v := range input {
temp := v
ch - temp
}
抑或直接引用數(shù)據(jù)的內(nèi)存(推薦,無需開辟新的內(nèi)存空間):
for k, _ := range input {
c - input[k]
}
再次運行,就可看到預(yù)期的效果。以上方案是用于討論 range 語句帶來的問題,當然,平時還是盡量避免使用指針類型的通道。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- Go語言應(yīng)該什么情況使用指針
- Go 語言的指針的學(xué)習(xí)筆記
- Go語言中結(jié)構(gòu)體方法副本傳參與指針傳參的區(qū)別介紹
- golang中值類型/指針類型的變量區(qū)別總結(jié)
- golang方法中receiver為指針與不為指針的區(qū)別詳析
- Go語言中的指針運算實例分析
- Go語言指針訪問結(jié)構(gòu)體的方法
- Go語言指針使用分析與講解