AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁 > 科技  > 軟件

Go 面試中的隱藏陷阱:SliceHeader 問題解析

來源: 責(zé)編: 時間:2024-06-12 17:31:35 133觀看
導(dǎo)讀大家好,我是煎魚。最近也是面試季+畢業(yè)季了,很多同學(xué)正在積極準(zhǔn)備面試。尤其是很多同學(xué),已經(jīng)通過官網(wǎng)資料熟悉了 Go 基本語法,但沒有太大把握。希望對一些常見的棘手面試問題做一些預(yù)習(xí)。今天和大家學(xué)習(xí) @Harutyun Mardir

大家好,我是煎魚。rkt28資訊網(wǎng)——每日最新資訊28at.com

最近也是面試季+畢業(yè)季了,很多同學(xué)正在積極準(zhǔn)備面試。尤其是很多同學(xué),已經(jīng)通過官網(wǎng)資料熟悉了 Go 基本語法,但沒有太大把握。希望對一些常見的棘手面試問題做一些預(yù)習(xí)。rkt28資訊網(wǎng)——每日最新資訊28at.com

今天和大家學(xué)習(xí) @Harutyun Mardirossian 大佬分享的面試題,一起進(jìn)步!rkt28資訊網(wǎng)——每日最新資訊28at.com

面試問題

請先在腦子里思考一下具體的運(yùn)行結(jié)果,再查看答案。rkt28資訊網(wǎng)——每日最新資訊28at.com

如下代碼:rkt28資訊網(wǎng)——每日最新資訊28at.com

func main() {    s := make([]int, 0, 2)    doSomething(s)    fmt.Println(s)}func doSomething(a []int) {    a = append(a, 1)}

面試問題:fmt.Println 的輸出結(jié)果是什么?rkt28資訊網(wǎng)——每日最新資訊28at.com

問題解析

運(yùn)行程序,查看輸出結(jié)果:rkt28資訊網(wǎng)——每日最新資訊28at.com

[]

fmt.Println 最終打印的是一個長度為 0 的切片。rkt28資訊網(wǎng)——每日最新資訊28at.com

答案是:空切片。(你答對了嗎?)rkt28資訊網(wǎng)——每日最新資訊28at.com

在 Go 中,函數(shù)參數(shù)是按值傳遞的,這意味著上述代碼在參數(shù)傳遞時,創(chuàng)建了參數(shù)值的副本并傳遞給函數(shù)。rkt28資訊網(wǎng)——每日最新資訊28at.com

而切片實際上是一個包含長度(len)、容量(cap)和指向底層數(shù)組指針(data)的結(jié)構(gòu)體。rkt28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們將切片作為函數(shù)參數(shù)傳遞時,實質(zhì)上復(fù)制的是切片的 SliceHeader,對應(yīng)的底層數(shù)組是保持不變的。rkt28資訊網(wǎng)——每日最新資訊28at.com

結(jié)合代碼來講,就是因為在 doSomething 函數(shù)中,創(chuàng)建了 SliceHeader 的新副本。然后 append 函數(shù)會在超過容量時重新分配新切片,并返回更新后的切片。rkt28資訊網(wǎng)——每日最新資訊28at.com

深入驗證

我們可以使用 unsafe 包去打印 SliceHeader(切片頭),進(jìn)行進(jìn)一步的驗證和分析。rkt28資訊網(wǎng)——每日最新資訊28at.com

如下代碼:rkt28資訊網(wǎng)——每日最新資訊28at.com

type SliceHeader struct {    Data uintptr    Len  int    Cap  int}func main() {    s := make([]int, 0, 2)    sh := (*SliceHeader)(unsafe.Pointer(&s))    fmt.Println(sh)    doSomething(s)}func doSomething(a []int) {    a = append(a, 1)    sh := (*SliceHeader)(unsafe.Pointer(&a))    fmt.Println(sh)}

輸出結(jié)果:rkt28資訊網(wǎng)——每日最新資訊28at.com

&{1374389592336 0 2} // main&{1374389592336 1 2} // doSomething

兩個切片的 Data 指針地址指向的是同一個底層數(shù)組。但由于長度不同,它們在應(yīng)用的表現(xiàn)上是兩個不同的切片。rkt28資訊網(wǎng)——每日最新資訊28at.com

這也印證了前面問題的結(jié)果是輸出了空切片,切片長度為 0 的內(nèi)部原理。rkt28資訊網(wǎng)——每日最新資訊28at.com

變通方法

這種情況下,建議是修改寫法,提高代碼易讀性。否則后續(xù)維護(hù)也比較麻煩,不熟悉的同學(xué)咋一眼一看很有可能發(fā)現(xiàn)不了問題。rkt28資訊網(wǎng)——每日最新資訊28at.com

但如果你還是希望輸出你想要的切片值,可以采取以下變通方法。rkt28資訊網(wǎng)——每日最新資訊28at.com

改動后的代碼:rkt28資訊網(wǎng)——每日最新資訊28at.com

func main() {    s := make([]int, 0, 2)    doSomething(s)    fmt.Println(s[:1]) // 進(jìn)行新的切片操作}func doSomething(a []int) {    a = append(a, 1)}

輸出結(jié)果:rkt28資訊網(wǎng)——每日最新資訊28at.com

[1]

原因是在進(jìn)行 s[:1] 切片操作時,本質(zhì)上是創(chuàng)建了一個新的 SliceHeader,所以可以正常打印和獲取預(yù)期的元素。rkt28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然,還有一種常見的寫法就是切片 append 等變更后一定做一遍再賦值,這樣可以規(guī)避掉不少使用上的細(xì)節(jié)坑。rkt28資訊網(wǎng)——每日最新資訊28at.com

總結(jié)

今天這篇文章討論了一個很常見的 Go 面試問題,內(nèi)容涉及切片作為函數(shù)參數(shù)的傳遞和修改。rkt28資訊網(wǎng)——每日最新資訊28at.com

重點在于切片作為參數(shù)是按值傳遞的,因此函數(shù)內(nèi)部的修改不會影響外部變量。rkt28資訊網(wǎng)——每日最新資訊28at.com

如果仍然希望獲取可以通過切片操作,重新切分一下新的切片結(jié)果集就可以了。rkt28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-93368-0.htmlGo 面試中的隱藏陷阱:SliceHeader 問題解析

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C#托管堆遭破壞問題溯源分析

下一篇: 基于 Spring Boot 與 WebSocket 實現(xiàn)實時車位管理與狀態(tài)更新

標(biāo)簽:
  • 熱門焦點
Top