Golang string参数传递小记

本文探讨了Golang中string类型作为函数参数传递的细节,通过查看汇编代码揭示了字符串在函数调用过程中的值传递特性。分析了简单函数、同步闭包以及goroutine闭包三种情况下的字符串处理方式,强调了由于Go中string的不可变性,即使传递的是地址,也无法在函数内部修改原始值。此外,对于闭包函数,特别是goroutine中的闭包,由于可能存在栈帧销毁的问题,字符串和其他变量通常会被打包在堆中分配,确保闭包的正确执行。
摘要由CSDN通过智能技术生成

Golang中string类型作为函数参数进行传递的时候背后是怎么实现的呢?本文通过查看Golang汇编结果进行一些insight。

编译Golang汇编命令:

GOOS=linux GOARCH=amd64 go tool compile -S -N xxx.go > xxx.s

第一个案例——简单的函数参数传递

Go代码:

package main
//go:noinline
func foo(s string) {
   
	s = "this is a change"
}
func main() {
   
	s := "hello world"
	foo(s)
}

注意为了防止函数在编译过程中被内联优化,使用了go:noinline。汇编结果(简明考虑删去了一些不重要的内容):

"".foo STEXT nosplit size=22 args=0x10 locals=0x0
        0x0000 00000 (func_string.go:5) LEAQ    go.string."this is a change"(SB), AX # C
        0x0007 00007 (func_string.go:5) MOVQ    AX, "".s+8(SP)                       # C
        0x000c 00012 (func_string.go:5) MOVQ    $16, "".s+16(SP)                     # C
        0x0015 00021 (func_string.go:6) RET
"".main STEXT size=85 args=0x0 locals=0x28
        0x0000 00000 (func_string.go:8) MOVQ    (TLS), CX
        0x0009 00009 (func_string.go:8) CMPQ    SP, 16(CX)
        0x000d 00013 (func_string.go:8) JLS     78
        0x000f 00015 (func_string.go:8) SUBQ    $40, SP
        0x0013 00019 (func_string.go:8) MOVQ    BP, 32(SP)
        0x0018 00024 (func_string.go:8) LEAQ    32(SP), BP
        0x001d 00029 (func_string.go:9) LEAQ    go.string."hello world"(SB), AX # A
        0x0024 00036 (func_string.go:9) MOVQ    AX, "".s+16(SP)                 # A
        0x0029 00041 (func_string.go:9) MOVQ    $11, "".s+24(SP)                # A
        0x0032 00050 (func_string.go:10)        MOVQ    AX, (SP)                # B
        0x0036 00054 (func_string.go:10)        MOVQ    $11, 8(SP)              # B
        0x003f 00063 (func_string.go:10)        CALL    "".foo(SB)
        0x0044 00068 (func_string.go:11)        MOVQ    32(SP), BP
        0x0049 00073 (func_string.go:11)        ADDQ    $40, SP
        0x004d 00077 (func_string.go:11)        RET
        0x004e 00078 (func_string.go:11)        NOP
        0x004e 00078 (func_string.go:8) CALL    runtime.morestack_noctxt(SB)
        0x0053 00083 (func_string.go:8) JMP     0
go.string."this is a change" SRODATA dupok size=16
        0x0000 74 68 69 73 20 69 73 20 61 20 63 68 61 6e 67 65  this is a change
go.string."hello world" SRODATA dupok size=11
        0x0000 68 65 6c 6c 6f 20 77 6f 72 6c 64                 hello world

main函数中,A处将hello world字符串的地址保存在了SP&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值