go - 如何理解 uintptr 和 struct 之间的关系?
问题描述
我已经学习了如下代码
func str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0], x[1], x[1]}
return *(*[]byte)(unsafe.Pointer(&h))
}
此功能是更改string
为[]byte
无阶段复制数据。
我尝试将 num 转换为 reverseNum
type Num struct {
name int8
value int8
}
type ReverseNum struct {
value int8
name int8
}
func main() {
n := Num{100, 10}
z := (*[2]uintptr)(unsafe.Pointer(&n))
h := [2]uintptr{z[1], z[0]}
fmt.Println(*(*ReverseNum)(unsafe.Pointer(&h))) // print result is {0, 0}
}
这段代码没有得到我想要的结果。谁能告诉我
解决方案
这太复杂了。
更简单的
package main
import (
"fmt"
"unsafe"
)
type Num struct {
name int8
value int8
}
type ReverseNum struct {
value int8
name int8
}
func main() {
n := Num{name: 42, value: 12}
p := (*ReverseNum)(unsafe.Pointer(&n))
fmt.Println(p.value, p.name)
}
输出“42, 12”。
但真正的问题是,你到底为什么要使用这种诡计而不是复制两个在运行任何明智的 CPU 围棋程序上立即完成的怪异字节?
您的方法的另一个问题是,IIUC 在Go 语言规范中没有任何内容保证具有看似相同字段的两种类型必须具有相同的内存布局。我相信他们应该在大多数实施中,但我认为他们不需要这样做。
还要考虑看似无害的事情,例如在您的数据类型中还有一个额外的字段(甚至类型!)可能会对这些类型的变量的内存布局产生有趣的影响,因此假设您可能重新解释Go 的内存可能是完全危险的变你想要的方式。struct{}
推荐阅读
- ios - 应用加载时,TabView 正在加载所有应用选项卡
- python - 我无法访问 Google 共享云端硬盘中的共享文件
- sql - 如果在块 1 中没有找到记录,则执行另一个块
- java - 有没有办法将 CONTENT_LENGTH 与 reactor-netty 中的内容一起发送
- python - 使用保存的 BERT 模型对文本进行分类的预测器预测功能
- angular - Angular - 为什么我的组件从服务中的 Observable 获得默认值,尽管它之前已经更改过?
- java - 如何在查询前解析正斜杠
- python - 如何按 Pandas 中的 2 个多索引列对 sort_values() 进行排序
- python-3.x - Stereo SGBM 与 WLS 视差图中的视差值差异
- r - 向 pheatmap 添加信息