【发布时间】:2015-12-18 11:51:43
【问题描述】:
考虑到您可以(想不出一个很好的表达方式,但是)在 Go 中操作指针,是否可以像在 C 中那样执行指针运算,比如迭代数组?我知道这些天循环对于这类事情很好,但我只是好奇它是否可能。
【问题讨论】:
标签: pointers go pointer-arithmetic
考虑到您可以(想不出一个很好的表达方式,但是)在 Go 中操作指针,是否可以像在 C 中那样执行指针运算,比如迭代数组?我知道这些天循环对于这类事情很好,但我只是好奇它是否可能。
【问题讨论】:
标签: pointers go pointer-arithmetic
没有。来自Go FAQ:
为什么没有指针运算?
安全。如果没有指针算法,就有可能创建一种永远不会得出错误成功的非法地址的语言。编译器和硬件技术已经发展到使用数组索引的循环可以与使用指针算法的循环一样高效的程度。此外,指针算法的缺乏可以简化垃圾收集器的实现。
话虽如此,您可以使用 unsafe 包解决此问题,但只是不要:
package main
import "fmt"
import "unsafe"
func main() {
vals := []int{10, 20, 30, 40}
start := unsafe.Pointer(&vals[0])
size := unsafe.Sizeof(int(0))
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Pointer(uintptr(start) + size*uintptr(i)))
fmt.Println(item)
}
}
【讨论】:
//go:nosplit,否则您可能会破坏 gc 的状态。
从 Go 1.17 开始,我们现在有了 unsafe.Add,这使它更容易一些:
package main
import (
"unsafe"
)
func main() {
vals := []int{10, 20, 30, 40}
ptrStart := unsafe.Pointer(&vals[0])
itemSize := unsafe.Sizeof(vals[0])
for i := 0; i < len(vals); i++ {
item := *(*int)(unsafe.Add(ptrStart, uintptr(i)*itemSize))
println(item)
}
}
【讨论】: