Go中的指针运算
Pointer arithmetic in Go
考虑到您可以(想不出一个很好的表达方式,但是)在 Go 中操作指针,是否可以像在 C 中那样执行指针运算,比如遍历数组?我知道现在循环对于这类事情来说很好,但我只是好奇它是否可能。
没有。来自 Go FAQ:
Why is there no pointer arithmetic?
Safety. Without pointer arithmetic it's possible to create a language that can never derive an illegal address that succeeds incorrectly. Compiler and hardware technology have advanced to the point where a loop using array indices can be as efficient as a loop using pointer arithmetic. Also, the lack of pointer arithmetic can simplify the implementation of the garbage collector.
也就是说,您可以使用 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 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)
}
}
考虑到您可以(想不出一个很好的表达方式,但是)在 Go 中操作指针,是否可以像在 C 中那样执行指针运算,比如遍历数组?我知道现在循环对于这类事情来说很好,但我只是好奇它是否可能。
没有。来自 Go FAQ:
Why is there no pointer arithmetic?
Safety. Without pointer arithmetic it's possible to create a language that can never derive an illegal address that succeeds incorrectly. Compiler and hardware technology have advanced to the point where a loop using array indices can be as efficient as a loop using pointer arithmetic. Also, the lack of pointer arithmetic can simplify the implementation of the garbage collector.
也就是说,您可以使用 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 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)
}
}