unsafe
Publish on 2024-09-19
  1. unsafe 包提供了 2 点重要的能力:
  2. 任何类型的指针和 unsafe.Pointer 可以相互转换。uintptr 类型和 unsafe.Pointer 可以相互转换。

Untitled.png

pointer 不能直接进行数学运算,但可以把它转换成 uintptr,对 uintptr 类型进行数学运算,再转换成 pointer 类型。

func main() {
	p := Programmer{"stefno", 18, "go"}
	fmt.Println(p)

	lang := (*string)(unsafe.Pointer(uintptr(unsafe.Pointer(&p)) + unsafe.Sizeof(int(0)) + unsafe.Sizeof(string(""))))
	*lang = "Golang"

	fmt.Println(p)
}
// uintptr 是一个整数类型,它足够大,可以存储
type uintptr uintptr

如下,map从汇编上可以知道是*hmap类型的,但是语言层面可见的就是map结构。Pointer可以转化的必要条件是语言(语法检查工具)可见范围内要出现取引用符&

package main

import (
	"fmt"
	"unsafe"
)

type myInt int
type myIntPtr *int

func main() {
	mp := make(map[string]int)
	mp["qcrao"] = 100
	mp["stefno"] = 18

	count := *(**int)(unsafe.Pointer(&mp))
	fmt.Println(count, len(mp)) // 2 2

	var fooi myInt = 1
	var i int = 5
	var fooip myIntPtr = &i

	fmt.Println(unsafe.Pointer(fooip))
	fmt.Println(unsafe.Pointer(&fooi))
}

还有一点要注意的是,uintptr 并没有指针的语义,意思就是 uintptr 所指向的对象会被 gc 无情地回收。而 unsafe.Pointer 有指针语义,可以保护它所指向的对象在“有用”的时候不会被垃圾回收。

© 2024 humbornjo :: based on 
nobloger  ::  rss