国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Golang】Golang進階系列教程--為什么 Go for-range 的 value 值地址每次都一樣?

這篇具有很好參考價值的文章主要介紹了【Golang】Golang進階系列教程--為什么 Go for-range 的 value 值地址每次都一樣?。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

循環(huán)語句是一種常用的控制結(jié)構(gòu),在 Go 語言中,除了 for 關(guān)鍵字以外,還有一個 range 關(guān)鍵字,可以使用 for-range 循環(huán)迭代數(shù)組、切片、字符串、map 和 channel 這些數(shù)據(jù)類型。

但是在使用 for-range 循環(huán)迭代數(shù)組和切片的時候,是很容易出錯的,甚至很多老司機一不小心都會在這里翻車。

具體是怎么翻的呢?我們接著看。

現(xiàn)象

先來看兩段很有意思的代碼:

無限循環(huán)

如果我們在遍歷數(shù)組的同時向數(shù)組中添加元素,能否得到一個永遠都不會停止的循環(huán)呢?
比如下面這段代碼:

func main() {
    arr := []int{1, 2, 3}
    for _, v := range arr {
        arr = append(arr, v)
    }
    fmt.Println(arr)
}

程序輸出:

$ go run main.go
1 2 3 1 2 3

上述代碼的輸出意味著循環(huán)只遍歷了原始切片中的三個元素,我們在遍歷切片時追加的元素并沒有增加循環(huán)的執(zhí)行次數(shù),所以循環(huán)最終還是停了下來。

相同地址

第二個例子是使用 Go 語言經(jīng)常會犯的一個錯誤。

當我們在遍歷一個數(shù)組時,如果獲取 range 返回變量的地址并保存到另一個數(shù)組或者哈希時,會遇到令人困惑的現(xiàn)象:

func main() {
    arr := []int{1, 2, 3}
    newArr := []*int{}
    for _, v := range arr {
        newArr = append(newArr, &v)
    }
    for _, v := range newArr {
        fmt.Println(*v)
    }
}

程序輸出:

$ go run main.go
3 3 3

上述代碼并沒有輸出 1 2 3,而是輸出 3 3 3。
正確的做法應(yīng)該是使用 &arr[i] 替代 &v,像這種編程中的細節(jié)是很容易出錯的。

原因

具體原因也并不復(fù)雜,一句話就能解釋。

對于數(shù)組、切片或字符串,每次迭代,for-range 語句都會將原始值的副本傳遞給迭代變量,而非原始值本身。

口說無憑,具體是不是這樣,還得靠源碼說話。

Go 編譯器會將 for-range 語句轉(zhuǎn)換成類似 C 語言的三段式循環(huán)結(jié)構(gòu),就像這樣:

// Arrange to do a loop appropriate for the type.  We will produce
//   for INIT ; COND ; POST {
//           ITER_INIT
//           INDEX = INDEX_TEMP
//           VALUE = VALUE_TEMP // If there is a value
//           original statements
//   }

迭代數(shù)組時,是這樣:

// The loop we generate:
//   len_temp := len(range)
//   range_temp := range
//   for index_temp = 0; index_temp < len_temp; index_temp++ {
//           value_temp = range_temp[index_temp]
//           index = index_temp
//           value = value_temp
//           original body
//   }

切片:

//   for_temp := range
//   len_temp := len(for_temp)
//   for index_temp = 0; index_temp < len_temp; index_temp++ {
//           value_temp = for_temp[index_temp]
//           index = index_temp
//           value = value_temp
//           original body
//   }

從上面的代碼片段,可以總結(jié)兩點:

  • 在循環(huán)開始前,會將數(shù)組或切片賦值給一個新變量,在賦值過程中就發(fā)生了拷貝,迭代的實際上是副本,這也就解釋了現(xiàn)象 1。

  • 在循環(huán)過程中,會將迭代元素賦值給一個臨時變量,這又發(fā)生了拷貝。如果取地址的話,每次都是一樣的,都是臨時變量的地址。

  • 參考文章:

garbagecollected.org/2017/02/22/…
draveness.me/golang/docs…文章來源地址http://www.zghlxwxcb.cn/news/detail-619233.html

推薦閱讀

  • Go 語言教程–介紹(一)
  • Go 語言教程–語言結(jié)構(gòu)(二)
  • Go 語言教程–語言結(jié)構(gòu)(三)
  • Go 語言教程–數(shù)據(jù)類型(四)
  • Go 語言教程–語言變量(五)
  • Go 語言教程–GO語言常量(六)
  • Go 語言教程–GO語言運算符(七)
  • Go 語言教程–GO條件和循環(huán)語句(八)
  • Go 語言教程–GO語言函數(shù)(九)
  • Go 語言教程–GO語言變量作用域(十)
  • Go 語言教程–GO語言數(shù)組(十一)
  • Go 語言教程–GO語言指針(十二)
  • Go 語言教程–GO語言結(jié)構(gòu)體(十三)
  • Go 語言教程–GO語言切片(Slice)(十四)
  • Go 語言教程–Go 語言范圍(Range)(十五)
  • Go 語言教程–Go 語言Map(集合)(十六)
  • Go 語言教程–Go 語言遞歸函數(shù)(十七)
  • Go 語言教程–Go 語言類型轉(zhuǎn)換(十八)
  • Go 語言教程–Go 語言接口(十九)
  • Go 語言教程–Go 錯誤處理(二十)
  • Go 語言教程–Go 并發(fā)(二十一)

到了這里,關(guān)于【Golang】Golang進階系列教程--為什么 Go for-range 的 value 值地址每次都一樣?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【Golang】三分鐘讓你快速了解Go語言&為什么我們需要Go語言?

    【Golang】三分鐘讓你快速了解Go語言&為什么我們需要Go語言?

    博主簡介: 努力學(xué)習(xí)的大一在校計算機專業(yè)學(xué)生,熱愛學(xué)習(xí)和創(chuàng)作。目前在學(xué)習(xí)和分享:數(shù)據(jù)結(jié)構(gòu)、Go,Java等相關(guān)知識。 博主主頁: @是瑤瑤子啦 所屬專欄: Go語言核心編程 近期目標: 寫好專欄的每一篇文章 Go 語言從 2009 年 9 月 21 日開始作為谷歌公司 20% 兼職項目,即相關(guān)

    2023年04月21日
    瀏覽(29)
  • 是時候回答【我為什么要學(xué)習(xí) Go 語言(golang)】這個問題了

    想必每個人在學(xué)習(xí)新事物之前,都會捫心自問:“我為什么要學(xué)習(xí)它呢?” 正如我們讀 四大名著 一般,也只有在您讀過了 四大名著 后,再細看中國幾千年歷史不就是 天下大勢合久必分,分久必合 ,再者,便是與友數(shù)人相聚,席間您述說您通勤時所遇到有意思的事了,而您

    2023年04月09日
    瀏覽(19)
  • 【Golang】一篇文章帶你快速了解Go語言&為什么你要學(xué)習(xí)Go語言

    【Golang】一篇文章帶你快速了解Go語言&為什么你要學(xué)習(xí)Go語言

    目錄 1. 為什么互聯(lián)網(wǎng)世界需要Go語言 1.1 硬件限制:摩爾定律已然失效? 1.2 Go語言為并發(fā)而生 1.3 Go性能強悍 1.4 Go語言簡單易學(xué) 1.4.1 語法簡潔 1.4.2 代碼風格統(tǒng)一 1.4.3開發(fā)效率高? 2.Go語言的誕生與發(fā)展 2.1什么是Go語言? ?2.2 Go語言的誕生 2.3?Go Gopher——Go語言的吉祥物 3. 為什么

    2024年02月04日
    瀏覽(37)
  • 【Golang】Golang進階系列教程--Go 語言 map 如何順序讀???

    Go 語言中的 map 是一種非常強大的數(shù)據(jù)結(jié)構(gòu),它允許我們快速地存儲和檢索鍵值對。 然而,當我們遍歷 map 時,會有一個有趣的現(xiàn)象,那就是輸出的鍵值對順序是不確定的。 先看一段代碼示例: 當我們多執(zhí)行幾次這段代碼時,就會發(fā)現(xiàn),輸出的順序是不同的。 首先,Go 語言

    2024年02月14日
    瀏覽(96)
  • 【Golang】Golang進階系列教程--Go 語言切片是如何擴容的?

    【Golang】Golang進階系列教程--Go 語言切片是如何擴容的?

    在 Go 語言中,有一個很常用的數(shù)據(jù)結(jié)構(gòu),那就是切片(Slice)。 切片是一個擁有相同類型元素的可變長度的序列,它是基于數(shù)組類型做的一層封裝。它非常靈活,支持自動擴容。 切片是一種引用類型,它有三個屬性:指針,長度和容量。 底層源碼定義如下: 指針: 指向

    2024年02月14日
    瀏覽(103)
  • 【Golang】Golang進階系列教程--Go 語言數(shù)組和切片的區(qū)別

    【Golang】Golang進階系列教程--Go 語言數(shù)組和切片的區(qū)別

    在 Go 語言中,數(shù)組和切片看起來很像,但其實它們又有很多的不同之處,這篇文章就來說說它們到底有哪些不同。 數(shù)組和切片是兩個常用的數(shù)據(jù)結(jié)構(gòu)。它們都可以用于存儲一組相同類型的元素,但在底層實現(xiàn)和使用方式上存在一些重要的區(qū)別。 Go 中數(shù)組的長度是不可改變的

    2024年02月15日
    瀏覽(31)
  • 【Golang 接口自動化00】為什么要用Golang做自動化?

    【Golang 接口自動化00】為什么要用Golang做自動化?

    目錄 為什么使用Golang做自動化 最終想實現(xiàn)的效果 怎么做? 寫在后面 ?資料獲取方法 順應(yīng)公司的趨勢學(xué)習(xí)了Golang之后,因為沒有太多時間和項目來實踐,怕止步于此、步Java缺少練習(xí)遺忘殆盡的后塵,決定利用工作之余的時間把此前用Python的寫的自動化使用golang進行重構(gòu)。

    2024年02月15日
    瀏覽(32)
  • Golang 中的 slice 為什么是并發(fā)不安全的?

    Golang 中的 slice 為什么是并發(fā)不安全的?

    ??在Go語言中,slice是并發(fā)不安全的,主要有以下兩個原因:數(shù)據(jù)競爭、內(nèi)存重分配。 ??數(shù)據(jù)競爭:slice底層的結(jié)構(gòu)體包含一個指向底層數(shù)組的指針和該數(shù)組的長度,當多個協(xié)程并發(fā)訪問同一個slice時,有可能會出現(xiàn)數(shù)據(jù)競爭的問題。例如,一個協(xié)程在修改slice的長度,而

    2024年02月05日
    瀏覽(27)
  • Golang對比Java、python為什么要保留指針

    平時我們在Golang使用指針一般是為了以下的情況: 方法直接修改原來對象 保證參數(shù)傳遞的自由,可以在傳遞重量級對象時使用指針 但Go 保留指針不僅僅是為了解決傳遞參數(shù)的問題,還跟它的語言特性有密不可分的聯(lián)系。 Go 里面的變量是 值語義 ,這個跟 C/C++是一脈相承的。

    2024年01月17日
    瀏覽(31)
  • Golang 中的 map 為什么是并發(fā)不安全的?

    Golang 中的 map 為什么是并發(fā)不安全的?

    ??golang 中的 map 是并發(fā)不安全的,多個 go 協(xié)程同時對同一個 map 進行讀寫操作時,會導(dǎo)致數(shù)據(jù)競爭(data race)問題,程序會 panic。 ??如果一個協(xié)程正在寫入 map,而另一個協(xié)程正在讀取或?qū)懭?map,那么就有可能出現(xiàn)一些未定義的行為,例如:讀取到的值可能是過期的、不

    2024年02月05日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包