欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang中for range的取地址操作陷阱介紹

 更新時間:2021年04月26日 08:32:58   作者:qauzy  
這篇文章主要介紹了golang中for range的取地址操作陷阱,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

Tips:for range創(chuàng)建了每個元素的副本,而不是直接返回每個元素的引用

例子1:

package main
import "fmt"
func main() {
 slice := []int{0, 1, 2, 3}
 myMap := make(map[int]*int)
 for index, value := range slice {
  myMap[index] = &value
 }
 fmt.Println("=====new map=====")
 prtMap(myMap)
}
 
func prtMap(myMap map[int]*int) {
 for key, value := range myMap {
  fmt.Printf("map[%v]=%v\n", key, *value)
 }
}

輸出:

dotzdeMacBook-Pro-2:src dotz$ ./range

=====new map=====

map[0]=3

map[1]=3

map[2]=3

map[3]=3

例子2:

package main  
import "fmt"  
type Test struct {
    name string
}
 
func (this *Test) Point() { // this  為指針
    fmt.Println(this.name)
}
  
func main() {  
    ts := []Test{{"a"}, {"b"}, {"c"}}
    for _, t := range ts {
        defer t.Point() //輸出 c c c
    } 
} 

輸出:

dotzdeMacBook-Pro-2:src dotz$ ./method

c

c

c

例子1 我們預期輸出0,1,2,3,例子2 我們預期輸出a,b, c,但兩個例子的輸出都不是我們預期的。

對于例子1,比較明顯,執(zhí)行了取地址操作,每次都取value變量的地址,所以最后map中的所有元素的值都是value變量的地址(引用),因為最后value被賦值為3,所有輸出都是3.

對于例子2,隱晦一點,夾雜了defer和方法接收者的規(guī)則,但其實也和例子1一樣,執(zhí)行t.Point()時,得到的是t的地址(引用),for結束時,t被賦值為”c“的地址,main函數返回時,都在執(zhí)行”c“的接收方法Point,所以輸出都是”c".

補充:golang取地址操作采坑:for idx,item := range arr中的item是個獨立對象

先看代碼:

package main
import "fmt"
func main() {
    type s struct {
        A string
        B int32
    }
    arr := []s{
        {"123", 123},
        {"456", 456},
        {"789", 789},
    }
    m := make(map[string]*s)
    for idx, item := range arr {
        m[item.A] = &item
        fmt.Printf("idx=%d, addr=%p, item addr=%p\n", idx, &arr[idx], &item)
    }
    for k, v := range m {
        fmt.Printf("key=%s, v=%+v\n", k, v)
    }
}

運行輸出:

idx=0, addr=0xc00004e050, item addr=0xc0000044a0

idx=1, addr=0xc00004e068, item addr=0xc0000044a0

idx=2, addr=0xc00004e080, item addr=0xc0000044a0

key=123, v=&{A:789 B:789}

key=456, v=&{A:789 B:789}

key=789, v=&{A:789 B:789}

我傻傻的在循環(huán)中取item的地址,結果所有map中的值都指向最后一個!

看來item是一個獨立對象,這個對象指向了數組中的對應元素。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關文章

  • Golang?sync.Once實現單例模式的方法詳解

    Golang?sync.Once實現單例模式的方法詳解

    Go?語言的?sync?包提供了一系列同步原語,其中?sync.Once?就是其中之一。本文將深入探討?sync.Once?的實現原理和使用方法,幫助大家更好地理解和應用?sync.Once,需要的可以參考一下
    2023-05-05
  • Go1.18新特性工作區(qū)模糊測試及泛型的使用詳解

    Go1.18新特性工作區(qū)模糊測試及泛型的使用詳解

    這篇文章主要為大家介紹了Go?1.18新特性中的工作區(qū)?模糊測試?泛型使用進行詳細講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • Go歸并排序算法的實現方法

    Go歸并排序算法的實現方法

    歸并排序采用的也是分治的策略,把原本的問題先分解成一些小問題進行求解,再把這些小問題各自的答案修整到一起得到原本問題的答案,從而達到分而治之的目的,對Go歸并排序算法相關知識感興趣的朋友一起看看吧
    2022-04-04
  • 初步解讀Golang中的接口相關編寫方法

    初步解讀Golang中的接口相關編寫方法

    這篇文章主要介紹了Golang中的接口相關編寫方法,是Go語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-11-11
  • Go語言Gin處理響應方式詳解

    Go語言Gin處理響應方式詳解

    gin框架封裝了常用的數據格式方法響應于客戶端,下面這篇文章主要給大家介紹了關于Go語言Gin處理響應方式的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • 深入解析Go語言中上下文超時與子進程管理

    深入解析Go語言中上下文超時與子進程管理

    這篇文章小編將通過一個實際問題的案例,和大家深入探討一下Go語言中的上下文超時和子進程管理,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-10-10
  • 更高效的GoLevelDB:shardingdb實現分片和并發(fā)讀寫操作

    更高效的GoLevelDB:shardingdb實現分片和并發(fā)讀寫操作

    這篇文章主要介紹了更高效的GoLevelDB:shardingdb實現分片和并發(fā)讀寫操作的相關資料,需要的朋友可以參考下
    2023-09-09
  • Golang WebView跨平臺的桌面應用庫的使用

    Golang WebView跨平臺的桌面應用庫的使用

    Golang WebView是一個強大的桌面應用庫,本文介紹了Golang WebView的特點和使用方法,并列舉示例詳細的介紹了其在實際項目中的應用,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • Golang實現Json分級解析及數字解析實踐詳解

    Golang實現Json分級解析及數字解析實踐詳解

    你是否遇到過在無法準確確定json層級關系的情況下對json進行解析的需求呢?本文就來和大家介紹一次解析不確定的json對象的經歷,以及遇到的問題和解決方法
    2023-02-02
  • 淺析Go中fasthttp與net/http的性能對比及應用

    淺析Go中fasthttp與net/http的性能對比及應用

    這篇文章主要為大家詳細介紹了Golang中fasthttp的底層實現以及與net/http的區(qū)別,下面就跟隨小編一起來看看fasthttp到底是如何做到性能如此之快的吧
    2024-03-03

最新評論