I saw this guy, and he wrote this code:
func foo1() *string {
var pointa *string
pointa = new(string)
*pointa = "stuff"
return pointa
}
Very nice, very nice, however, can't help but notice that one could also write:
func foo2() *string {
var pointa *string
var str = "stuff"
pointa = &str
return pointa
}
The first code says:
The second code says:
&
, it will be allocated dynamicallyAm I right about these assumptions?
Are these 2 dynamic string allocations equivalent?
Is new(string); *pointer = "payload"
exactly what is happening in the second code, but under the hood, implicitly?
Are these pieces of code gonna produce the same code that allocated and initializes the string?
The Go specification makes no guarantees, and whatever answer you discover today is subject to change without warning, but you can see for yourself using the version of gc
available a godbolt.org that all three versions of your function produce identical output, differing only in the names and values of the string (stuff1/stuff2/stuff3):
https://godbolt.org/z/evP1M3fs5
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;
}
Output:
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