最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go?for-range?的?value值地址每次都一樣的原因解析

 更新時間:2023年05月01日 07:38:02   作者:AlwaysBeta  
循環(huán)語句是一種常用的控制結構,在?Go?語言中,除了?for?關鍵字以外,還有一個?range?關鍵字,可以使用?for-range?循環(huán)迭代數(shù)組、切片、字符串、map?和?channel?這些數(shù)據(jù)類型,這篇文章主要介紹了Go?for-range?的?value值地址每次都一樣的原因解析,需要的朋友可以參考下

循環(huán)語句是一種常用的控制結構,在 Go 語言中,除了 for 關鍵字以外,還有一個 range 關鍵字,可以使用 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 語言經常會犯的一個錯誤。

當我們在遍歷一個數(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。

正確的做法應該是使用 &arr[i] 替代 &v,像這種編程中的細節(jié)是很容易出錯的。

原因

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

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

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

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

// 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
//   }

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

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

參考文章:

到此這篇關于Go for-range 的 value 值地址每次都一樣的原因解析的文章就介紹到這了,更多相關Go for-range 的 value 值地址內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解Golang 中的并發(fā)限制與超時控制

    詳解Golang 中的并發(fā)限制與超時控制

    這篇文章主要介紹了詳解Golang 中的并發(fā)限制與超時控制,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Hugo 游樂場內容初始化示例詳解

    Hugo 游樂場內容初始化示例詳解

    這篇文章主要為大家介紹了Hugo 游樂場內容初始化示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • GoFrame框架數(shù)據(jù)校驗之校驗結果Error接口對象

    GoFrame框架數(shù)據(jù)校驗之校驗結果Error接口對象

    這篇文章主要為大家介紹了GoFrame框架數(shù)據(jù)校驗之校驗結果Error接口對象示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • golang中字符串MD5生成方式總結

    golang中字符串MD5生成方式總結

    在本篇文章里小編給大家整理的是一篇關于golang中字符串MD5生成方式總結內容,有興趣的朋友們可以跟著學習參考下。
    2021-07-07
  • Go語言文件操作的方法

    Go語言文件操作的方法

    這篇文章主要介紹了Go語言文件操作的方法,涉及文件的讀寫及關閉等操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • golang中protobuf的使用詳解

    golang中protobuf的使用詳解

    protobuf是Google公司提出的一種輕便高效的結構化數(shù)據(jù)存儲格式,常用于結構化數(shù)據(jù)的序列化,具有語言無關、平臺無關、可擴展性特性,常用于通訊協(xié)議、服務端數(shù)據(jù)交換場景,下面我們就來看看golang中protobuf的具體使用吧
    2023-10-10
  • Go語言七篇入門教程四通道及Goroutine

    Go語言七篇入門教程四通道及Goroutine

    這篇文章主要為大家介紹了Go語言的通道及Goroutine示例詳解,本文是Go語言七篇入門系列篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • beego獲取ajax數(shù)據(jù)的實例

    beego獲取ajax數(shù)據(jù)的實例

    下面小編就為大家分享一篇beego獲取ajax數(shù)據(jù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • goquery 入門(安裝使用教程)

    goquery 入門(安裝使用教程)

    這篇文章主要為大家介紹了goquery 入門(安裝使用)教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    這篇文章主要為大家介紹了Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12

最新評論

枞阳县| 永德县| 马边| 开平市| 固阳县| 宁津县| 同德县| 隆安县| 巴塘县| 城固县| 镇原县| 凯里市| 四川省| 汾西县| 保亭| 吕梁市| 张家港市| 西宁市| 加查县| 姚安县| 北碚区| 剑河县| 武陟县| 大城县| 蓬溪县| 临清市| 临泽县| 工布江达县| 中宁县| 阳朔县| 西畴县| 嵊州市| 呈贡县| 灵石县| 开平市| 兴海县| 太湖县| 涟源市| 新晃| 南安市| 峨眉山市|