第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

關(guān)于映射、字符串指針和閉包的問題

關(guān)于映射、字符串指針和閉包的問題

Go
藍(lán)山帝景 2022-06-13 15:03:41
當(dāng)我嘗試轉(zhuǎn)換為時(shí),我發(fā)現(xiàn)我的代碼存在錯(cuò)誤(我map[string]string正在map[string]*string使用的 API 需要轉(zhuǎn)換)。問題在我的第一個(gè)方法中,我嘗試遍歷源映射中的每個(gè)條目,aMap并將每個(gè)條目的字符串值轉(zhuǎn)換為字符串指針,并將此指針值分配給目標(biāo)映射,bMap與aMap. 我最初預(yù)計(jì)保留的取消引用值bMap與aMap同一鍵下的值相同。但是,事實(shí)證明,在同一鍵下, 的延遲值bMap不共享相同的值。aMap我的問題是:為什么會(huì)出現(xiàn)這個(gè)問題?我能夠使用第二種方法解決該問題,首先定義一個(gè)接收字符串并返回指針的函數(shù),這樣我就能夠正確返回延遲值以共享與aMap同一鍵下相同的值。為什么這種方法有效?另外,只是好奇,為什么&(*v)Go 中有語(yǔ)法錯(cuò)誤?我還嘗試聲明一個(gè)虛擬變量val := *v,并將其分配給bMapusingbMap[key] = &val但無濟(jì)于事。錯(cuò)誤說invalid indirect of v (type string)源代碼https://play.golang.org/p/ZG7XS2vJx0yfunc main() {    aMap := make(map[string]string)    aMap["foo"] = "bar"    aMap["bar"] = "baz"    aMap["baz"] = "foo"    bMap := make(map[string]*string)    for k, v := range(aMap){        bMap[k] = &v    }    // first method    fmt.Println("1st method, map[string]*string, bMap")     for k, v := range(bMap){        fmt.Printf("bMap[%s] = %s / %s, aMap[%s] = %s\n",        k, *bMap[k], *v, k, aMap[k])    }    pString := func(v string) *string{ return &v }    for k, v := range(aMap){        bMap[k] = pString(v)    }    // second method    fmt.Println("2nd method, map[string]*string, bMap")    for k, v := range(bMap){        fmt.Printf("bMap[%s] = %s / %s, aMap[%s] = %s\n",        k, *bMap[k], *v, k, aMap[k])    }    // expected results    fmt.Println("Expected result: map[string]string, cMap")    cMap := make(map[string]string)    for k, v := range(aMap){        cMap[k] = v    }    for k, v := range(cMap){        fmt.Printf("cMap[%s] = %s / %s, aMap[%s] = %s\n",        k, cMap[k], v, k, aMap[k])    }}輸出1st method, map[string]*string, bMapbMap[baz] = foo / foo, aMap[baz] = foobMap[foo] = foo / foo, aMap[foo] = barbMap[bar] = foo / foo, aMap[bar] = baz2nd method, map[string]*string, bMapbMap[baz] = foo / foo, aMap[baz] = foobMap[foo] = bar / bar, aMap[foo] = barbMap[bar] = baz / baz, aMap[bar] = bazExpected result: map[string]string, cMapcMap[baz] = foo / foo, aMap[baz] = foocMap[foo] = bar / bar, aMap[foo] = barcMap[bar] = baz / baz, aMap[bar] = baz太感謝了。
查看完整描述

2 回答

?
牧羊人nacy

TA貢獻(xiàn)1862條經(jīng)驗(yàn) 獲得超7個(gè)贊

方法 1 中的問題是您沒有獲取字符串的地址,而是獲取了它所在變量的地址。在 Go 中,&v返回變量的地址v。當(dāng)你有這樣的循環(huán)時(shí):


for k, v := range aMap {

    ...

}

您在循環(huán)開始時(shí)聲明的變量k和v在整個(gè)循環(huán)中使用的變量是相同的。它們只是在每次迭代中被分配了不同的值。在該循環(huán)中,&v總是計(jì)算出相同的值: 的地址v。這就是為什么您的所有地圖條目都出現(xiàn)在"foo":"foo"中的最后一個(gè)值v,并且它仍然存在。


您可以通過更改字符串值來查看此行為。所有的地圖鍵都會(huì)改變:


*bMap["foo"] = "quux"

fmt.Println(*bMap["bar"]) // prints "quux"

方法 2 有效,因?yàn)楹瘮?shù)的每次調(diào)用都有自己的局部變量。Go 保證,如果您從函數(shù)返回局部變量的地址,該變量將被分配在堆上,只要需要它就可以使用它。所以你的輔助函數(shù)告訴 Go 分配一個(gè)新string變量,將傳入的字符串復(fù)制到它,然后返回它的地址。


這是另一種可行的方法:


dMap := make(map[string]*string)

for k, v := range(aMap){

    dMap[k] = new(string)

    *dMap[k] = v

}

這會(huì)分配一個(gè)新的字符串變量,將其地址保存在映射中,然后將 v 復(fù)制到其中。如果您要經(jīng)常這樣做,輔助函數(shù)可能是最好的。


您嘗試的代碼如下:


v := "foo"

val := *v

bMap[key] = &val

不起作用,因?yàn)槟f“v 是一個(gè)字符串;現(xiàn)在將字符串指向的值存儲(chǔ)在 val 中”,但該字符串不是指針。


查看完整回答
反對(duì) 回復(fù) 2022-06-13
?
嗶嗶one

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊

問題中的第一種方法使用v所有鍵的單個(gè)循環(huán)變量的地址。您看到的值是最后一個(gè)設(shè)置為 的值v。


通過為每次迭代聲明一個(gè)新變量并獲取該變量的地址來修復(fù)。


bMap := make(map[string]*string)

for k, v := range aMap {

    v := v // declare new variable v initialized with value from outer v

    bMap[k] = &v

}

問題中的第二種方法還為循環(huán)中的每次迭代聲明了一個(gè)新變量。新變量是函數(shù)參數(shù)。


這個(gè)答案顯示了解決這個(gè)問題的慣用方法。請(qǐng)參閱Go 常見問題解答:作為 goroutine 運(yùn)行的閉包會(huì)發(fā)生什么?在閉包和 goroutine 的上下文中討論相同的問題。


查看完整回答
反對(duì) 回復(fù) 2022-06-13
  • 2 回答
  • 0 關(guān)注
  • 144 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)