日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Go语言中append()函数的源码实现在哪里?

發布時間:2023/12/19 综合教程 26 生活家
生活随笔 收集整理的這篇文章主要介紹了 Go语言中append()函数的源码实现在哪里? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天在學習Go的基礎數據結構——slice,期間閱讀了slice的內部實現,擴容策略等。然后想到,我們在調用append()函數進行追加元素是究竟發生了什么?于是就想看看append()函數的內部實現,結果源碼里并沒有找到,搜索一番,還是在StackOverflow上找到了答案。記錄如下。

Q:Where is the implementation of func append in Go?

A:

The code you are reading and citing is just dummy code to have consistent documentation. The built-in functions are, well, built into the language and, as such, are included in the code processing step (the compiler).

Simplified what happens is: lexer(詞法分析程序) will detect 'append(...)' asAPPENDtoken, parser will translateAPPEND, depending on the circumstances/parameters/environment to code, code is written as assembly and assembled(代碼被寫成匯編語言,然后進行編譯). The middle step - the implementation ofappend- can be found in the compilerhere.

What happens to anappendcall is best seen when looking at the assembly of an example program. Consider this:

b := []byte{'a'}
b = append(b, 'b')
println(string(b), cap(b))

Running it will yield the following output:

ab 2

Theappendcall is translated to assembly like this:

// create new slice object
MOVQ    BX, "".b+120(SP)       // BX contains data addr., write to b.addr
MOVQ    BX, CX                 // store addr. in CX
MOVQ    AX, "".b+128(SP)       // AX contains len(b) == 1, write to b.len
MOVQ    DI, "".b+136(SP)       // DI contains cap(b) == 1, write to b.cap
MOVQ    AX, BX                 // BX now contains len(b)
INCQ    BX                     // BX++
CMPQ    BX, DI                 // compare new length (2) with cap (1)
JHI $1, 225                    // jump to grow code if len > cap
...
LEAQ    (CX)(AX*1), BX         // load address of newly allocated slice entry
MOVB    $98, (BX)              // write 'b' to loaded address

// grow code, call runtime.growslice(t *slicetype, old slice, cap int)
LEAQ    type.[]uint8(SB), BP
MOVQ    BP, (SP)               // load parameters onto stack
MOVQ    CX, 8(SP)
MOVQ    AX, 16(SP)
MOVQ    SI, 24(SP)
MOVQ    BX, 32(SP)
PCDATA  $0, $0
CALL    runtime.growslice(SB)  // call
MOVQ    40(SP), DI
MOVQ    48(SP), R8
MOVQ    56(SP), SI
MOVQ    R8, AX
INCQ    R8
MOVQ    DI, CX
JMP 108                        // jump back, growing done

As you can see, noCALLstatement to a function calledappendcan be seen. This is the full implementation of theappendcall in the example code. Another call with different parameterswilllook differently (other registers, different parameters depending on the slice type, etc.).


參考:

https://stackoverflow.com/questions/33405327/where-is-the-implementation-of-func-append-in-go

總結

以上是生活随笔為你收集整理的Go语言中append()函数的源码实现在哪里?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。