我注意到,在某些版本的 Go 上,有时第一个和第二个 int 变量之间的差距会增加。
package main
import (
"fmt"
"unsafe"
)
func main() {
a := 7
b := 8
c := 9
d := 10
fmt.Printf("a's address is %v\n", &a)
fmt.Printf("b's address is %v\n", &b)
fmt.Printf("c's address is %v\n", &c)
fmt.Printf("d's address is %v\n", &d)
baSpan := uintptr(unsafe.Pointer(&b)) - uintptr(unsafe.Pointer(&a))
cbSpan := uintptr(unsafe.Pointer(&c)) - uintptr(unsafe.Pointer(&b))
dcSpan := uintptr(unsafe.Pointer(&d)) - uintptr(unsafe.Pointer(&c))
// Go playground, Go 1.20 - Prints 8.
// Go playground, Go dev branch - Sometimes prints 8, sometimes 24.
// My machine, go1.20.4 windows/amd64 - Always prints 24.
fmt.Printf("b-a span is %v\n", baSpan)
fmt.Printf("c-b span is %v\n", cbSpan) // Prints 8
fmt.Printf("d-c span is %v\n", dcSpan) // Prints 8
}
去游乐场,go1.20 - https://go.dev/play/p/BJIVC1cQQoT
去游乐场,去开发 - https://go.dev/play/p/BJIVC1cQQoT?v=gotip
问题是:
a
在 64 位机器上占用 8 个字节)堆分配取决于实现和运行时。
x.go
:
package main
import (
"fmt"
"unsafe"
)
func main() {
a := 7
b := 8
c := 9
d := 10
fmt.Printf("a's address is %v\n", &a)
fmt.Printf("b's address is %v\n", &b)
fmt.Printf("c's address is %v\n", &c)
fmt.Printf("d's address is %v\n", &d)
baSpan := uintptr(unsafe.Pointer(&b)) - uintptr(unsafe.Pointer(&a))
cbSpan := uintptr(unsafe.Pointer(&c)) - uintptr(unsafe.Pointer(&b))
dcSpan := uintptr(unsafe.Pointer(&d)) - uintptr(unsafe.Pointer(&c))
fmt.Printf("b-a span is %v\n", baSpan)
fmt.Printf("c-b span is %v\n", cbSpan)
fmt.Printf("d-c span is %v\n", dcSpan)
}
./x.go:9:2: moved to heap: a
./x.go:10:2: moved to heap: b
./x.go:11:2: moved to heap: c
./x.go:12:2: moved to heap: d
go1.20 version && go1.20 build -gcflags='-m' x.go && ./x
go version go1.20.7 linux/amd64
a's address is 0xc000018130
b's address is 0xc000018138
c's address is 0xc000018140
d's address is 0xc000018148
b-a span is 8
c-b span is 8
d-c span is 8
go1.21 version && go1.21 build -gcflags='-m' x.go && ./x
go version go1.21rc4 linux/amd64
a's address is 0xc00009c010
b's address is 0xc00009c018
c's address is 0xc00009c020
d's address is 0xc00009c028
b-a span is 8
c-b span is 8
d-c span is 8
go version && go build -gcflags='-m' x.go && ./x
go version devel go1.22-4e728e5121 Mon Aug 7 16:07:50 2023 +0000 X:loopvar linux/amd64
a's address is 0xc00009c010
b's address is 0xc00009c018
c's address is 0xc00009c020
d's address is 0xc00009c028
b-a span is 8
c-b span is 8
d-c span is 8
https://go.dev/play/p/HeAMYeBG1_o?v=go1.20
a's address is 0xc0000b2000
b's address is 0xc0000b2008
c's address is 0xc0000b2010
d's address is 0xc0000b2018
b-a span is 8
c-b span is 8
d-c span is 8
https://go.dev/play/p/HeAMYeBG1_o?v=gotip
a's address is 0xc000012028
b's address is 0xc000012040
c's address is 0xc000012048
d's address is 0xc000012050
b-a span is 24
c-b span is 8
d-c span is 8