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

深入理解go slice結(jié)構(gòu)

 更新時(shí)間:2021年09月14日 15:51:53   作者:好吃嗎  
這篇文章主要介紹了go slice結(jié)構(gòu),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

文章

slice介紹

append的機(jī)制

slice tricks

go data

slice

array的語(yǔ)法: [4]int{1,2,3,4}, [...]int{1,2,3}。在go中array是值類(lèi)型,這就意味著一個(gè)類(lèi)型為array的變量名并不是一個(gè)指針,當(dāng)傳遞值是,array總是被復(fù)制。

slice的語(yǔ)法: []int{1,2,3,4}, make([]int), make([]int,10)

當(dāng)make只有兩個(gè)參數(shù)時(shí),cap和len相同。

slice本質(zhì)上是array的一個(gè)片段的描述,它包含3部分:
[ptr, len, cap]

通過(guò)make([]int, 5)創(chuàng)建的slice,其內(nèi)存布局如下:

在這里插入圖片描述

對(duì)這個(gè)slice進(jìn)行截?cái)嘀?,形成新的slice:

在這里插入圖片描述

使用cap可以對(duì)slice進(jìn)行擴(kuò)增: s[:cap(s)].

copy(dst, src []T) int的用法: copy會(huì)復(fù)制dst和src中長(zhǎng)度最小的元素所對(duì)應(yīng)的數(shù)量(所以如果dst==nil, 則copy返回0)。并且,copy還能處理dst和src存在重疊的情況。
用法:

t := make([]byte, len(s), (cap(s)+1)*2)
copy(t, s)
s = t

append(dst []T, element...T) []T的實(shí)現(xiàn),與下面的AppendByte類(lèi)似:
首先檢查容量,容量不足則使用make構(gòu)造一個(gè)新的slice并將原來(lái)的元素移動(dòng)。

func AppendByte(slice []byte, data ...byte) []byte {
    m := len(slice)
    n := m + len(data)
    if n > cap(slice) { // if necessary, reallocate
        // allocate double what's needed, for future growth.
        newSlice := make([]byte, (n+1)*2)
        copy(newSlice, slice)
        slice = newSlice
    }
    slice = slice[0:n]
    copy(slice[m:n], data)
    return slice
}

slice對(duì)gc的影響(gotcha)

如果對(duì)一個(gè)很大的數(shù)組,取其中很小的一段切片,都會(huì)造成這個(gè)數(shù)組不會(huì)被gc回收。
gc使用mark-and-sweep(標(biāo)記清除)。gc維護(hù)一個(gè)已分配的堆對(duì)象表,在標(biāo)記階段,它將寄存器,堆棧上的指針作為root進(jìn)行遍歷標(biāo)記。

為什么部分slice會(huì)導(dǎo)致整體的array不會(huì)回收呢?設(shè)想下面的slice:

a := [4]int{0,1,2,3}
s := a[1:2] // {1}
return s

a會(huì)不會(huì)被回收呢?答案是不會(huì),因?yàn)間c遍歷s時(shí),通過(guò)data指針找到對(duì)應(yīng)的array切片,它發(fā)現(xiàn)這個(gè)地址在之前分配的一個(gè)array對(duì)象的范圍內(nèi),從而標(biāo)記這個(gè)array為可到達(dá)對(duì)象,避免其被整個(gè)清除。(這里所要理解的就是array是按范圍標(biāo)記的,并不是按指針頭標(biāo)記的,因?yàn)橐粋€(gè)內(nèi)存塊對(duì)象是有范圍的,如果被部分引用,說(shuō)明整個(gè)對(duì)象仍然是可達(dá)的。)

如何解決?如果是這種情況,一個(gè)較大array返回較小切片,可以使用復(fù)制:

before:

var digitRegexp = regexp.MustCompile("[0-9]+")

func FindDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    return digitRegexp.Find(b)
}

after:

func CopyDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    b = digitRegexp.Find(b)
    c := make([]byte, len(b))
    copy(c, b)
    return c
}

reflect.SliceHeader

package reflect

// SliceHeader和StringHeader具有相同的Data和Len,這導(dǎo)致[]byte可以直接轉(zhuǎn)換成string,而不需要任何復(fù)制
type SliceHeader struct {
	Data uintptr
	Len  int
	Cap  int
}
type StringHeader struct {
	Data uintptr
	Len  int
}

轉(zhuǎn)換代碼:

func SliceByteAsString(b []byte) string {
    return *(*string)(unsafe.Pointer(&b))
}
func StringAsSliceByte(s string) []byte {
    p := unsafe.Pointer(&d)
    var b []byte
    hdr :=  (*reflect.SliceHeader)(unsafe.Pointer(&b))
    hdr.Data = uintptr(p)
    hdr.Cap = len(s)
    hdr.Len = len(s)
    return b
}

func Int64AsByteSlice(d int64) []byte {
    p := unsafe.Pointer(&d)
    var b []byte
    hdr :=  (*reflect.SliceHeader)(unsafe.Pointer(&b))
    hdr.Data = uintptr(p)
    hdr.Cap = 8
    hdr.Len = 8
    return b
}

到此這篇關(guān)于go slice結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)go slice結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringEvent優(yōu)雅解耦時(shí)連續(xù)兩個(gè)bug的解決方案

    SpringEvent優(yōu)雅解耦時(shí)連續(xù)兩個(gè)bug的解決方案

    這篇文章主要為大家介紹了SpringEvent優(yōu)雅解耦時(shí)連續(xù)兩個(gè)bug的解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • go語(yǔ)言限制協(xié)程并發(fā)數(shù)的方案詳情

    go語(yǔ)言限制協(xié)程并發(fā)數(shù)的方案詳情

    一個(gè)線程中可以有任意多個(gè)協(xié)程,但某一時(shí)刻只能有一個(gè)協(xié)程在運(yùn)行,多個(gè)協(xié)程分享該線程分配到的計(jì)算機(jī)資源,接下來(lái)通過(guò)本文給大家介紹go語(yǔ)言限制協(xié)程的并發(fā)數(shù)的方案詳情,感興趣的朋友一起看看吧
    2022-01-01
  • Go?多環(huán)境下配置管理方案(多種方案)

    Go?多環(huán)境下配置管理方案(多種方案)

    這篇文章主要介紹了Go?多環(huán)境下配置管理方案,方案一配置文件管理,方案二集中式管理配置,每種方案給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • 詳解Go語(yǔ)言中獲取文件路徑的不同方法與應(yīng)用場(chǎng)景

    詳解Go語(yǔ)言中獲取文件路徑的不同方法與應(yīng)用場(chǎng)景

    在使用?Go?開(kāi)發(fā)項(xiàng)目時(shí),估計(jì)有不少人遇到過(guò)無(wú)法正確處理文件路徑的問(wèn)題,本文將嘗試從簡(jiǎn)單到復(fù)雜,詳細(xì)介紹?Go?中獲取路徑的不同方法及應(yīng)用場(chǎng)景,希望對(duì)大家有所幫助
    2024-02-02
  • goland中文件頭自動(dòng)注釋的操作

    goland中文件頭自動(dòng)注釋的操作

    這篇文章主要介紹了goland中文件頭自動(dòng)注釋的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • 創(chuàng)建Go工程化項(xiàng)目布局詳解

    創(chuàng)建Go工程化項(xiàng)目布局詳解

    這篇文章主要介紹了創(chuàng)建Go工程化項(xiàng)目布局詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • golang判斷結(jié)構(gòu)體為空的問(wèn)題

    golang判斷結(jié)構(gòu)體為空的問(wèn)題

    這篇文章主要介紹了golang判斷結(jié)構(gòu)體為空的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • GoLang日志監(jiān)控系統(tǒng)實(shí)現(xiàn)

    GoLang日志監(jiān)控系統(tǒng)實(shí)現(xiàn)

    這篇文章主要介紹了GoLang日志監(jiān)控系統(tǒng)的實(shí)現(xiàn)流程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-12-12
  • Go語(yǔ)言學(xué)習(xí)筆記之反射用法詳解

    Go語(yǔ)言學(xué)習(xí)筆記之反射用法詳解

    這篇文章主要介紹了Go語(yǔ)言學(xué)習(xí)筆記之反射用法,詳細(xì)分析了Go語(yǔ)言中反射的概念、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-05-05
  • Golang拾遺之指針和接口的使用詳解

    Golang拾遺之指針和接口的使用詳解

    拾遺主要是收集和golang相關(guān)的瑣碎知識(shí),這篇文章主要是為大家整理了Golang中指針和接口的使用方法,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-02-02

最新評(píng)論

台州市| 舞钢市| 华坪县| 东丰县| 潮州市| 甘洛县| 吴桥县| 荔波县| 浙江省| 汨罗市| 客服| 泽普县| 德州市| 唐河县| 辽阳县| 彰化市| 浠水县| 阿坝| 平远县| 红桥区| 克山县| 方正县| 怀宁县| 广昌县| 锦屏县| 平乡县| 满城县| 丰原市| 同仁县| 郓城县| 兴国县| 犍为县| 涪陵区| 邛崃市| 泰和县| 疏附县| 九龙坡区| 新野县| 巩义市| 保亭| 乐昌市|