關(guān)于Golang中range指針數(shù)據(jù)的坑詳解
前言
在Golang中使用 for range 語句進(jìn)行迭代非常的便捷,但在涉及到指針時(shí)就得小心一點(diǎn)了。
下面的代碼中定義了一個(gè)元素類型為 *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ùn)行一下程序,得到的輸出如下:
很明顯,程序并沒有達(dá)到預(yù)期的結(jié)果,那么問題出在哪里呢?我們將代碼稍作修改:
//receiver
for v := range ch {
fmt.Println(v)
}得到如下輸出:
0x416020
0x416020
0x416020
0x416020
0x416020
可以看到,5次輸出變量 v ( *int )都指向了同一個(gè)地址,返回去檢查一下發(fā)送部分代碼:
for _, v := range input {
ch <- &v
}問題正是出在這里,在 for range 語句中, v 變量用于保存迭代 input 數(shù)組所得的值,但是 v 只被聲明了一次,此后都是將迭代 input 出的值賦值給 v , v 變量的內(nèi)存地址始終未變,這樣再將 v 的地址發(fā)送給 ch 通道,發(fā)送的都是同一個(gè)地址,當(dāng)然無法達(dá)到預(yù)期效果。
解決方案:
引入一個(gè)中間變量,每次迭代都重新聲明一個(gè)變量 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ùn)行,就可看到預(yù)期的效果。以上方案是用于討論 range 語句帶來的問題,當(dāng)然,平時(shí)還是盡量避免使用指針類型的通道。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
解決vscode中g(shù)olang插件依賴安裝失敗問題
這篇文章主要介紹了解決vscode中g(shù)olang插件依賴安裝失敗問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08
解決Go中使用seed得到相同隨機(jī)數(shù)的問題
這篇文章主要介紹了Go中使用seed得到相同隨機(jī)數(shù)的問題,需要的朋友可以參考下2019-10-10
Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印
這篇文章主要介紹了Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
在Golang代碼中如何自動(dòng)生成版本號的方法示例
這篇文章主要給大家介紹了在Golang代碼中如何自動(dòng)生成版本號的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-07-07
Golang中空的切片轉(zhuǎn)化成 JSON 后變?yōu)?nbsp;null 問題的解決方案
在 Golang 中,經(jīng)常需要將其他類型(例如 slice、map、struct 等類型)的數(shù)據(jù)轉(zhuǎn)化為 JSON 格式,有時(shí)候轉(zhuǎn)化的結(jié)果并不是預(yù)期中的,例如將一個(gè)空的切片轉(zhuǎn)化為 JSON 時(shí),會變成"null",所以本文將給大家介紹一下解決方法,需要的朋友可以參考下2023-09-09
基于Go實(shí)現(xiàn)TCP長連接上的請求數(shù)控制
在服務(wù)端開啟長連接的情況下,四層負(fù)載均衡轉(zhuǎn)發(fā)請求時(shí),會出現(xiàn)服務(wù)端收到的請求qps不均勻的情況或是服務(wù)器無法接受到請求,因此需要服務(wù)端定期主動(dòng)斷開一些長連接,所以本文給大家介紹了基于Go實(shí)現(xiàn)TCP長連接上的請求數(shù)控制,需要的朋友可以參考下2024-05-05
golang操作連接數(shù)據(jù)庫實(shí)現(xiàn)mysql事務(wù)示例
這篇文章主要為大家介紹了golang操作連接數(shù)據(jù)庫實(shí)現(xiàn)mysql事務(wù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04

