go語言##1欄位中給大家介紹Golang 切片(Slice)底層原始碼,希望對需要的朋友有所幫助!
陣列
說切片前先說下陣列。陣列的兩個特性- 一段連續記憶體位址,每個元素都是連續的
- 元素的型別相同,並且元素個數固定
arr := [2]int{1,2}arr2 := arr fmt.Printf("%p %p",&arr ,&arr2)//切片slice1 := []int{1,2}slice2 := slice1 fmt.Printf("%p %p",slice1 ,slice2)
切片
切片(slice)是對陣列一個連續片段的引用,所以切片是一個引用類型.切片是一個長度可變的陣列。 Slice 的資料結構定義如下:runtime/slice.go#L13type slice struct { array unsafe.Pointer len int cap int}
- array 是底層陣列的位址
- len 切片的長度
- cap 切片的容量
建立切片
src/runtime/slice.go#L83func makeslice(et *_type, len, cap int) unsafe.Pointer { mem, overflow := math.MulUintptr(et.size, uintptr(cap)) .... return mallocgc(mem, et, true)}基本邏輯就是根據容量申請一塊記憶體。
切片擴容
擴充功能是當切片的長度大於容量的時候,底層陣列已經裝不下時func growslice(et *_type, old slice, cap int) slice { ... // 如果新要扩容的容量比原来的容量还要小,直接报panic if cap doublecap { newcap = cap } else { // 旧容量 小于1024,新容量= 旧容量 * 2 也就是扩容1倍 if old.cap 0 && writeBarrier.enabled { bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem-et.size+et.ptrdata) } } //移动到p memmove(p, old.array, lenmem) //返回slice结构,让slice.array指向p return slice{p, old.len, newcap}}
- 新申請容量cap,如果大於2倍舊容量(oldcap),要擴容的容量(newcap)=新申請容量cap
- 如果舊容量(oldcap)< 1024, 要擴容的容量(newcap)在舊容量(oldcap )基礎上擴容1倍,否則則擴容1/4
- 如果數值溢出,要擴容的容量= 新申請的容量
arr := make([]int,1024) arr = append(arr,1) fmt.Println(len(arr),cap(arr))// 1025,1280 arr1 := make([]int,10) arr1 = append(arr1,1) fmt.Println(len(arr1),cap(arr1))//11 20
- 注意事項: 切片共享底層數組,所以在切片賦值的時候,修改切片會導致底層數組改變,而產生BUG
- #
arr := []int{1,2,3,4} arr1 := arr[:2] //[1,2] arr1 = append(arr1,5) fmt.Println(arr[3]) //5 修改了底层数组 //例子2 arr3 := []int{1,2,3,4} arr4 := arr3[2:] arr4 = append(arr4,10)//扩容 不会影响arr3 fmt.Println(arr3)
//toPtr 目标地址 toLen目标长度 // width 元素大小 func slicecopy(toPtr unsafe.Pointer, toLen int, fromPtr unsafe.Pointer, fromLen int, width uintptr) int { //判断长度 if fromLen == 0 || toLen == 0 { return 0 } n := fromLen if toLen < n { n = toLen } //切片大小等于0 if width == 0 { return n } size := uintptr(n) * width //特殊处理 如果只有一个元素并且大小是1byte,那么指针直接转换即可 if size == 1 { *(*byte)(toPtr) = *(*byte)(fromPtr) } else { //从 fm.array 地址开始,拷贝到 to.array 地址之后 memmove(toPtr, fromPtr, size) } return n }
以上是閱讀Golang 切片(Slice)底層源碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

goisastrongchoiceforprojectsneedingsimplicity,績效和引發性,butitmaylackinadvancedfeatures and ecosystemmaturity.1)

Go'sinitfunctionandJava'sstaticinitializersbothservetosetupenvironmentsbeforethemainfunction,buttheydifferinexecutionandcontrol.Go'sinitissimpleandautomatic,suitableforbasicsetupsbutcanleadtocomplexityifoverused.Java'sstaticinitializersoffermorecontr

thecommonusecasesfortheinitfunctionoare:1)加載configurationfilesbeforeThemainProgramStarts,2)初始化的globalvariables和3)runningpre-checkSorvalidationsbeforEtheprofforeTheProgrecce.TheInitFunctionIsautefunctionIsautomentycalomationalmatomatimationalycalmatemationalcalledbebeforethemainfuniinfuninfuntuntion

ChannelsarecrucialingoforenablingsafeandefficityCommunicationBetnewengoroutines.theyfacilitateSynChronizationAndManageGoroutIneLifeCycle,EssentialforConcurrentProgramming.ChannelSallSallSallSallSallowSallowsAllowsEnderDendingAndReceivingValues,ActassignalsignalsforsynChronization,and actassignalsynChronization and andsupppor

在Go中,可以通過errors.Wrap和errors.Unwrap方法來包裝錯誤並添加上下文。 1)使用errors包的新功能,可以在錯誤傳播過程中添加上下文信息。 2)通過fmt.Errorf和%w包裝錯誤,幫助定位問題。 3)自定義錯誤類型可以創建更具語義化的錯誤,增強錯誤處理的表達能力。

Gooffersrobustfeaturesforsecurecoding,butdevelopersmustimplementsecuritybestpracticeseffectively.1)UseGo'scryptopackageforsecuredatahandling.2)Manageconcurrencywithsynchronizationprimitivestopreventraceconditions.3)SanitizeexternalinputstoavoidSQLinj

Go的錯誤接口定義為typeerrorinterface{Error()string},允許任何實現Error()方法的類型被視為錯誤。使用步驟如下:1.基本檢查和記錄錯誤,例如iferr!=nil{log.Printf("Anerroroccurred:%v",err)return}。 2.創建自定義錯誤類型以提供更多信息,如typeMyErrorstruct{MsgstringDetailstring}。 3.使用錯誤包裝(自Go1.13起)來添加上下文而不丟失原始錯誤信息,

對效率的Handleerrorsinconcurrentgopragrs,UsechannelstocommunicateErrors,enplionErrorWatchers,Instertimeout,UsebufferedChannels和Provideclearrormessages.1)USEchannelelStopassErtopassErrorsErtopassErrorsErrorsErrorsFromGoroutInestOthemainFunction.2)


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中