func testMutex() {
stu := &Stu{
name: "song",
age: "12",
s: Stu1{name: "stu1"},
}
stu.st1 = &Stu{
name: "i amstu.st1",
age: "",
s: Stu1{},
st1: nil,
}
// 获取第一个
fmt.Println((*Stu)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)))).name)
i := *(*string)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("")))
// 获取第二个
fmt.Println(i)
// 获取第三个
ci := (*Stu1)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("") + unsafe.Sizeof("")))
fmt.Println(ci.name)
// 获取第四个
ci1 := *(*Stu)(unsafe.Pointer(uintptr(unsafe.Pointer(stu)) + unsafe.Sizeof("") + unsafe.Sizeof("") + unsafe.Sizeof(stu.s)))
fmt.Println(ci1)
}
type Stu struct {
name string
age string
s Stu1
st1 *Stu
}
type Stu1 struct {
name string
}
代码如上。 我发现 这样搞, 获取不到 Stu 里面的 st1 指针对象。 尴尬住了
![]() |
1
luguhu 225 天前
unsafe.Sizeof(reflect.ValueOf(stu.s))))
|
![]() |
2
luguhu 225 天前
用 unsafe.Sizeof(reflect.TypeOf(stu.s)) 才对
|
![]() |
3
Trim21 225 天前 via Android
直接用 unsafe.Offset…
|
![]() |
4
Trim21 225 天前 via Android
unsafe.Offset(Stu{}.s) 就是 s 的 offset 了。你这样手动拼接出来的不一定对。如果编译器做了 align 的话用 size 是没法得到正确结果的。
|
![]() |
7
Trim21 225 天前 ![]() @luguhu #6 有两个问题,一个是这样的 offset 可能是错的,另一个是你 st1 解引用的时候类型错了,应该用 *(**Stu)(unsafe.Add(p, unsafe.Offsetof(Stu{}.st1)))
https://go.dev/play/p/GsBLT4ENqN- 然后还有一个潜在问题,反射包里有一个未导出的方法 reflect.ifaceIndir ,如果一个结构体是 direct 的时候指针字段(包括 map 和 slice 等)还会各种奇怪的行为... |