go - 使用指针算法访问数组元素
问题描述
这是理解 golang 中内存寻址的唯一做法
当我将位添加到地址时,我想访问具有地址
byte
的数组元素,必须打印,它打印8
8
200
8
x := [15]byte{254, 200, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
地址 := &x[1]
unsafePointer := unsafe.Pointer(address)
fmt.Println(*(*uint8)(unsafe.Pointer(uintptr(unsafePointer)))) // ->254
fmt.Println(*(*uint8)(unsafe.Pointer(uintptr(unsafePointer)+8))) // ->8
解决方案
你做的算术uintptr(unsafePointer)
是以字节为单位的,而不是位。
无论如何,从 Go 1.17 开始,您可以使用unsafe.Add
指针算术:
函数 Add 将 len 添加到 ptr 并返回更新后的指针 Pointer(uintptr(ptr) + uintptr(len))。
package main
import (
"fmt"
"unsafe"
)
func main() {
x := [15]byte{254, 200, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
address := &x[0]
unsafePointer := unsafe.Pointer(address)
fmt.Println(*(*uint8)(unsafePointer)) // 254
fmt.Println(*(*uint8)(unsafe.Add(unsafePointer, 1))) // 200
fmt.Println(*(*uint8)(unsafe.Add(unsafePointer, 2))) // 2
}
游乐场: https: //play.golang.org/p/FS7GFN-P_Ez
为了清楚起见,len
您应该传递给unsafe.Add
的是元素的大小(以字节为单位),您可以使用unsafe.Sizeof
. 例如:
package main
import (
"fmt"
"unsafe"
)
type Foo struct {
Val int
}
func main() {
x := [...]Foo{newFoo(254), newFoo(200), newFoo(2)}
address := &x[0]
unsafePointer := unsafe.Pointer(address)
fmt.Println(*(*Foo)(unsafePointer)) // {254}
fmt.Println(*(*Foo)(unsafe.Add(unsafePointer, unsafe.Sizeof(Foo{})))) // {200}
fmt.Println(*(*Foo)(unsafe.Add(unsafePointer, unsafe.Sizeof(Foo{})*2))) // {2}
}
func newFoo(x int) Foo {
return Foo{x}
}
在您的示例中,添加无类型常量有效,因为数组元素是字节。
推荐阅读
- latex - 我的母语特殊字符在 LaTeX 上不起作用
- r - 过滤数据,逗号与非逗号
- azure - Azure Python Webapp 的 Github 操作:无法从发布配置文件获取凭据
- typescript - 离线后并非所有通知都显示
- java - 在 maven 项目中使用 jstl 从 MySQL 数据库中获取数据时出错
- assembly - 新组装,旨在打印 '0' 到 '9' ,意外错误
- c# - AutoMapper 全局前缀/后缀
- c# - 检测 C# 应用程序何时进入睡眠状态(未调用 SystemEvents.PowerModeChanged)
- c# - 当我输入条目时,轮播视图将我滚动到第一个项目
- python - 如何解决 403 错误抑制 Google Cloud Dataflow 可以启动的工作人员数量?