type Programmer struct {
name string
language string
}
funcmain() {
p := Programmer{"lisi", "go"}
name := (*string)(unsafe.Pointer(&p))
fmt.Println(name, *name) // 0xc0000203e0 lisi
language := (*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&p)) + unsafe.Offsetof(p.language)))
fmt.Println(language, *language) // 0xc0000203f0 go
}
type hmap struct {
// Note: the format of the hmap is also encoded in cmd/compile/internal/reflectdata/reflect.go.// Make sure this stays in sync with the compiler's definition.
count int// # live cells == size of map. Must be first (used by len() builtin)
flags uint8
B uint8// log_2 of # of buckets (can hold up to loadFactor * 2^B items)
noverflow uint16// approximate number of overflow buckets; see incrnoverflow for details
hash0 uint32// hash seed
buckets unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
nevacuate uintptr// progress counter for evacuation (buckets less than this have been evacuated)
extra *mapextra // optional fields
}
1. 和slice不同的是,makemap返回的是hmap的指针类型,注意是指针
`func makemap(t *maptype, hint int, h *hmap) *hmap {`
2. 我们依然能通过unsafe.Pointer和uintptr进行转换,得到hmap字段的值,只不过,
现在count变成二级指针了
funcmain() {
m := make(map[string]int)
m["age"] = 18
m["age2"] = 22
Len := **(**int)(unsafe.Pointer(&m))
fmt.Println(Len, len(m)) // 2 2
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)