这两个字符串分配等效吗?

2024年 2月 5日 107.9k 0

这两个字符串分配等效吗?

问题内容

我看到这个人,他写了这段代码:

func foo1() *string {
var pointa *string
pointa = new(string)
*pointa = "stuff"
return pointa
}

登录后复制

非常好,非常好,但是,不禁注意到人们还可以写:

func foo2() *string {
var pointa *string
var str = "stuff"
pointa = &str
return pointa
}

登录后复制

第一个代码表示:

  • 动态分配具有空底层存储的字符串容器
  • 使用该文字的内容覆盖底层存储
  • 我假设,由于COW,底层存储只是指向ELF数据段中的文字数据

第二个代码说:

  • 在本地分配字符串实例
  • 但由于稍后会通过引用 & 逃逸作用域,因此将动态分配
  • 但是,由于 COW,不会进行任何复制

我的这些假设正确吗?
这两个动态字符串分配等效吗?
new(string); *pointer = "payload" 到底在第二个代码中发生了什么,但是在幕后,隐式地发生了什么?

这些代码片段会产生与分配和初始化字符串相同的代码吗?

正确答案

Go 规范不做任何保证,无论您今天发现什么答案,都可能会在没有警告的情况下发生更改,但您可以使用 godbolt.org 上提供的 gc 版本亲自查看您的函数的所有三个版本都生成相同的输出,仅字符串的名称和值不同(stuff1/stuff2/stuff3):

https://www.php.cn/link/8a3a60ca2371a13fd1e84043f75f2f31

func foo1() *string {
var pointa *string
pointa = new(string)
*pointa = "stuff1"
return pointa
}

func foo2() *string {
var pointa *string
var str = "stuff2"
pointa = &str
return pointa
}

func foo3() *string {
x := "stuff3"
return &x;
}

登录后复制

输出:

main_foo1_pc0:
TEXT main.foo1(SB), ABIInternal, $24-0
CMPQ SP, 16(R14)
PCDATA $0, $-2
JLS main_foo1_pc50
PCDATA $0, $-1
PUSHQ BP
MOVQ SP, BP
SUBQ $16, SP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
LEAQ type:string(SB), AX
PCDATA $1, $0
CALL runtime.newobject(SB)
MOVQ $6, 8(AX)
LEAQ go:string."stuff1"(SB), CX
MOVQ CX, (AX)
ADDQ $16, SP
POPQ BP
RET
main_foo1_pc50:
NOP
PCDATA $1, $-1
PCDATA $0, $-2
CALL runtime.morestack_noctxt(SB)
PCDATA $0, $-1
JMP main_foo1_pc0
main_foo2_pc0:
TEXT main.foo2(SB), ABIInternal, $24-0
CMPQ SP, 16(R14)
PCDATA $0, $-2
JLS main_foo2_pc50
PCDATA $0, $-1
PUSHQ BP
MOVQ SP, BP
SUBQ $16, SP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
LEAQ type:string(SB), AX
PCDATA $1, $0
CALL runtime.newobject(SB)
MOVQ $6, 8(AX)
LEAQ go:string."stuff2"(SB), CX
MOVQ CX, (AX)
ADDQ $16, SP
POPQ BP
RET
main_foo2_pc50:
NOP
PCDATA $1, $-1
PCDATA $0, $-2
CALL runtime.morestack_noctxt(SB)
PCDATA $0, $-1
JMP main_foo2_pc0
main_foo3_pc0:
TEXT main.foo3(SB), ABIInternal, $24-0
CMPQ SP, 16(R14)
PCDATA $0, $-2
JLS main_foo3_pc50
PCDATA $0, $-1
PUSHQ BP
MOVQ SP, BP
SUBQ $16, SP
FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB)
LEAQ type:string(SB), AX
PCDATA $1, $0
CALL runtime.newobject(SB)
MOVQ $6, 8(AX)
LEAQ go:string."stuff3"(SB), CX
MOVQ CX, (AX)
ADDQ $16, SP
POPQ BP
RET
main_foo3_pc50:
NOP
PCDATA $1, $-1
PCDATA $0, $-2
CALL runtime.morestack_noctxt(SB)
PCDATA $0, $-1
JMP main_foo3_pc0

登录后复制

以上就是这两个字符串分配等效吗?的详细内容,更多请关注每日运维网(www.mryunwei.com)其它相关文章!

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论