go语言基本类型

类型名称 有无符号 占用位数
int8 Yes 8
int16 Yes 16
int32 Yes 32
int64 yes 64
uint8 No 8
uint16 No 16
uint32 No 32
uint64 No 64
int Yes 32或64,等于cpu位数
uint No 32或64,等于cpu位数
rune No 32,与uint32等价
byte No 8,与uint8等价
uintptr No 64,与uint64等价

rune 类型是 Unicode 字符类型,和 uint32 类型等价,通常用于表示一个 Unicode 字符。rune 和 uint32 可以互换使用。

byte 类型与uint8类型等价,byte类型一般用于强调数值是一个原始的内存数据而不是 一个小的整数。

uintptr 是一种无符号的整数类型,与uint64等价,范围:0 ~ 18446744073709551615,足以容纳任何指针值转换来的整型值。 uintptr类型只有在底层编程是才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。GC 不把 uintptr 当指针,uintptr 无法持有对象。uintptr 类型的目标会被回收,所以不要声明uintptr类型的变量

不管它们的具体大小,int、uint和uintptr是不同类型的兄弟类型。其中int和int32也是 不同的类型, 即使int的大小也是32bit,在需要将int当作int32类型的地方需要一个显式的类型转换操作,反之亦然

unsafe.Pointer

一个可以指向任意类型的指针,不可以进行数值计算
有四种区别于其他类型的特殊操作:
1. 任意类型的指针值均可转换为 Pointer
2. Pointer 均可转换为任意类型的指针值
3. uintptr 均可转换为 Pointer
4. Pointer 均可转换为 uintptr

unsafe 库让 golang 可以像C语言一样操作计算机内存,但这并不是golang推荐使用的,能不用尽量不用,就像它的名字所表达的一样,它绕过了golang的内存安全原则,是不安全的,容易使你的程序出现莫名其妙的问题,不利于程序的扩展与维护

示例1(unsafe.Pointer用来取地址,uintptr用来取地址的10进制数值):

package main
import ("fmt""unsafe"
)
func main() {a := int(5)p := &afmt.Println("p:", p)                                                     // a的地址,16进制形式fmt.Println("unsafe.Pointer(&a):", unsafe.Pointer(&a))                   // a的地址,16进制形式fmt.Println("uintptr(unsafe.Pointer(&a)):", uintptr(unsafe.Pointer(&a))) // a的地址,10进制形式
}

结果如下图:

PS:每次运行a的地址可能是不同的,但 unsafe.Pointer(&a) 和 uintptr(unsafe.Pointer(&a))的值是一样的,只是前者是指针类型,16进制,后者是整数类型,10进制,两者相等,这里 0xc00000a0b8,转换为10进制即 824633761976

示例2(地址计算,偏移,并修改)

package main
import ("fmt""unsafe"
)
func main() {a := [4]int{0, 1, 2, 3}p1 := unsafe.Pointer(&a[1]) // p1指向a[1]的起始地址// a[1]的地址类型转换为uintptr类型,后移2个元素的位置,这样移动到a[3]的起始地址位置p3 := unsafe.Pointer(uintptr(p1) + 2 * unsafe.Sizeof(a[0]))*(*int)(p3) = 6 // 先将Pointer类型转换为*int类型,再赋值fmt.Println("a =", a) // 打印出来结果是:a = [0 1 2 6]
}

结果如下图:

PS:unsafe.Pointer 是桥梁,可以让任意类型的指针实现相互转换,也可以将任意类型的指针转换为 uintptr 进行指针运

示例3(unsafe.Offsetof的使用)

该函数返回属性x的起始地址和结构体起始地址的字节数

func Offsetof(x ArbitraryType) uintptr

代码如下:

package main
import ("fmt""unsafe"
)
type Person struct {name   stringage    intgender bool
}
func main() {john := Person{"John", 30, true}pp := unsafe.Pointer(&john) // 结构体的起始地址pname := (*string)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(john.name)))  // 属性name的起始地址,转换为*string类型page := (*int)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(john.age)))         // 属性age的起始地址,转换为*int类型pgender := (*bool)(unsafe.Pointer(uintptr(pp) + unsafe.Offsetof(john.gender)))  // 属性gender的起始地址,转换为*bool类型// 进行赋值*pname = "Alice"*page = 28*pgender = falsefmt.Println(john) // {Alice 28 false}
}

实验结果如下:

go uintptr unsafe Pointer offset() 的使用相关推荐

  1. uintptr和unsafe.Pointer的区别

    unsafe.Pointer其实就是类似C的void *,在golang中是用于各种指针相互转换的桥梁.uintptr是golang的内置类型,是能存储指针的整型,uintptr的底层类型是int,它 ...

  2. Golang unsafe.Pointer指针

    相较于 C 而言,Go 语言在设计时为了使用安全给指针在类型和运算上增加了限制,这让Go程序员既可以享受指针带来的便利,又避免了指针的危险性.除了常规的指针外,Go 语言在 unsafe 包里其实还通 ...

  3. Go unsafe Pointer

    Go unsafe Pointer Go被设计为一种强类型的静态语言,强类型意味着类型一旦确定就无法更改,静态意味着类型检查在运行前就做了. 指针类型转换 为了安全考虑,两个不同类型的指针不能相互转换 ...

  4. Go 指针 unsafe.Pointer

    Go语言是个强类型语言.也就是说Go对类型要求严格,不同类型不能进行赋值操作.指针也是具有明确类型的对象,进行严格类型检查.下面的代码会产生编译错误 : package main import (&q ...

  5. 深度解密Go语言之unsafe

    上一篇文章我们详细分析了 map 的底层实现,如果你也跟着阅读了源码,那一定对 unsafe.Pointer 不陌生,map 对 key 进行定位的时候,大量使用. unsafe.Pointer 位于 ...

  6. go源码阅读笔记(unsafe)

    go源码阅读笔记(unsafe) unsafe 包主要是可以使得用户绕过go的类型规范检查,能够对指针以及其指向的区域进行读写操作. package mathimport "unsafe&q ...

  7. Go 学习笔记(74)— Go 标准库之 unsafe

    Go 语言自带的 unsafe 包的高级用法, 顾名思义,unsafe 是不安全的.Go 将其定义为这个包名,也是为了让我们尽可能地不使用它.不过虽然不安全,它也有优势,那就是可以绕过 Go 的内存安 ...

  8. runtime error: invalid memory address or nil pointer dereference

    runtime error: invalid memory address or nil pointer dereference 解决方法: tcallback((unsigned char*)pac ...

  9. Golang: unsafe包的使用

    1. golang各类型占空间字节数 package mainimport ("fmt""unsafe" )var tByte byte var tRune r ...

最新文章

  1. 2020 新兴技术炒作周期曲线:这 5 个趋势值得注意
  2. 关于助动词和过去分词的一点见解
  3. Web Service 学习笔记(2)
  4. Java基础 之软引用、弱引用、虚引用
  5. 段落排版--行间距, 行高(line-height)
  6. python模块:JSON模块
  7. JavaScript对象学习笔记
  8. Hello Quartz (第二部分)
  9. python开发环境一般用哪个快递_基于Python的常用快递sdk调用代码实例
  10. GlobalMapper20使用控制点对地形数据(高程数据)进行高程纠正(高程拟合/纠偏/配准)
  11. 软件测试:系统测试之因果图方法
  12. 项目时间进度计划与项目进度控制
  13. 24点递归实现(c语言)
  14. Python猴子补丁
  15. 深度学习Hello World --- 手写体识别 实战
  16. cfree 上面工具栏消失解决办法(不用重下!!!!!)
  17. 【2】输入俩个数m,n,字符串st1为1-m组成,输出字符串的倒数第n个字符
  18. Word产品需求文档,已经过时了
  19. 虚拟摄像头(拉rtsp流或桌面作为图像源)
  20. kubernetes节点NotReady

热门文章

  1. 《30天自制操作系统》前言、目录、样章欢迎阅读!
  2. CodeForces - 1341D Nastya and Scoreboard(dp+贪心)
  3. 二进制位交换,反转,与统计1的个数
  4. QT乱码总结3.UNICODE有无BOM
  5. 漫游Kafka实现篇之消息和日志
  6. 1_4 BuilderMode 建造者模式
  7. 网络优化实践探索文章
  8. 卧槽,又一款Markdown组合神器!!!
  9. 时钟源为什么会影响性能
  10. 区间调度之区间交集问题