Go语言中append()函数的源码实现在哪里?
今天在學(xué)習(xí)Go的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)——slice,期間閱讀了slice的內(nèi)部實現(xiàn),擴容策略等。然后想到,我們在調(diào)用append()函數(shù)進行追加元素是究竟發(fā)生了什么?于是就想看看append()函數(shù)的內(nèi)部實現(xiàn),結(jié)果源碼里并沒有找到,搜索一番,還是在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
總結(jié)
以上是生活随笔為你收集整理的Go语言中append()函数的源码实现在哪里?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SAP CRM WebClient UI
- 下一篇: SAP CRM WebClient UI