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

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

如何在 golang 中重用 slice with sync.Pool?

如何在 golang 中重用 slice with sync.Pool?

Go
富國(guó)滬深 2023-01-03 11:17:42
考慮這段代碼:type TestStruct struct {    Name string}func TestSliceWithPool(t *testing.T) {    var slicePool = sync.Pool{        New: func() interface{} {            t.Log("i am created")            s := make([]interface{}, 0)            return s        },    }    s, _ := slicePool.Get().([]interface{})    t.Logf("Lenth: %d, Cap: %d, Pointer: %p", len(s), cap(s), s)    for i := 0; i < 9000; i++ {        st := &TestStruct{Name: "test"}        s = append(s, st)    }    for _, v := range s {        if value, ok := v.(TestStruct); ok {            if value.Name != "test" {                t.Error("u are changed!")            }        }    }    s = s[:0]    slicePool.Put(s)    s2, _ := slicePool.Get().([]interface{})    t.Logf("Lenth: %d, Cap: %d, Pointer: %p", len(s), cap(s), s)    for i := 0; i < 8000; i++ {        st := &TestStruct{Name: "test2"}        s2 = append(s2, st)    }    for _, v := range s2 {        if value, ok := v.(TestStruct); ok {            if value.Name != "test2" {                t.Error("u are changed!")            }        }    }    slicePool.Put(s2)}測(cè)試結(jié)果為:slice_test.go:63: i am createdslice_test.go:70: Lenth: 0, Cap: 0, Pointer: 0x1019598slice_test.go:86: Lenth: 0, Cap: 9728, Pointer: 0xc000500000為什么只生成一次,地址卻不同?為什么上限是 9728?像這樣使用同一個(gè)切片有什么問題嗎?
查看完整描述

1 回答

?
斯蒂芬大帝

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

為什么只生成一次,地址卻不同?

因?yàn)樵诘谝粋€(gè) for 循環(huán)中,您將其追加到它的容量之外,它的 inNew設(shè)置為零,并將 的結(jié)果重新分配給它append。詳見:為什么append()會(huì)修改提供的切片?(見例子)

像這樣使用同一個(gè)切片有什么問題嗎?

可能有。當(dāng)您使用 reslices時(shí)s = s[:0],您重置的是長(zhǎng)度而不是容量。后備數(shù)組與之前的附加和重新分配操作中的相同。

因此,如果您再次追加到s2,容量將足以不會(huì)導(dǎo)致重新分配,并且您最終將覆蓋后備數(shù)組的第一個(gè)元素:

一個(gè)示范性的例子:

func TestSliceWithPool(t *testing.T) {

    var slicePool = sync.Pool{

        New: func() interface{} {

            t.Log("Created")

            s := make([]interface{}, 0)

            return s

        },

    }


    s, _ := slicePool.Get().([]interface{})

    for i := 0; i < 10; i++ {

        s = append(s, i)

    }

    fmt.Println(s) 

    // ^ output: [0 1 2 3 4 5 6 7 8 9]


    s = s[:0]

    slicePool.Put(s)


    s2, _ := slicePool.Get().([]interface{})

    fmt.Println(s)

    // ^ output: []


    for i := 0; i < 5; i++ {

        s2 = append(s2, i*10)

    }

    fmt.Println(s2) 

    // ^ output: [0 10 20 30 40]


    fmt.Println(s2[:10])

    // ^ output: [0 10 20 30 40 5 6 7 8 9]

}

這可能沒問題,因?yàn)槟悻F(xiàn)在有一個(gè)擴(kuò)展容量的切片,不需要在追加時(shí)重新分配,但如果你的應(yīng)用程序保持其他切片頭指向相同的支持?jǐn)?shù)組(如s和s2),從而防止緩沖區(qū)的垃圾收集。


查看完整回答
反對(duì) 回復(fù) 2023-01-03
  • 1 回答
  • 0 關(guān)注
  • 117 瀏覽
慕課專欄
更多

添加回答

舉報(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)