Go unsafe Pointer

Go被设计为一种强类型的静态语言,强类型意味着类型一旦确定就无法更改,静态意味着类型检查在运行前就做了。

指针类型转换

为了安全考虑,两个不同类型的指针不能相互转换,例如:

package mainfunc main() {i := 10ip := &ivar fp *float64 = (*float64)(ip)//会提示 Cannot convert an expression of the type '*int' to the type '*float64' 无法进行强制类型转换
}

如果非要进行转换,可以使用unsafe包中的Pointer

Pointer

unsafe.Pointer是一种特殊意义的指针。

package mainimport ("fmt""unsafe"
)func main() {i := 10ip := &ifp := (*float64)(unsafe.Pointer(ip))*fp = *fp * 3fmt.Println(i)
}
//output: 30

所以,使用unsafe.Pointer这个指针,我们可以在*T之间做任何转换。可以看到Pointer是一个 *int

type ArbitraryType int
type Pointer *ArbitraryType

我们可以看下关于unsafe.Pointer的四个原则:

  1. 任何指针都可以转换为unsafe.Pointer
  2. unsafe.Pointer可以转换为任何指针;
  3. uintptr可以转换为unsafe.Pointer
  4. unsafe.Pointer可以转换为uintptr

对于后面两个规则,我们知道*T是不能计算偏移量的,也不能进行计算。但是uintptr可以,我们可以把指针转换为uintptr再进行偏移计算,这样就可以访问特定的内存了,例如:

type user struct {name stringage  int
}func main() {u := new(user)fmt.Println(*u)pName := (*string)(unsafe.Pointer(u))*pName = "demo"pAge := (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(u)) + unsafe.Offsetof(u.age)))*pAge = 20fmt.Println(*u)
}
// output: {0}
//               {demo 20}

最后

unsafe是不安全的,应该尽量少的去使用。

Package unsafe contains operations that step around the type safety of Go programs.

Packages that import unsafe may be non-portable and are not protected by the Go 1 compatibility guidelines.

Go unsafe Pointer相关推荐

  1. Golang unsafe.Pointer指针

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

  2. Go 指针 unsafe.Pointer

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

  3. go uintptr unsafe Pointer offset() 的使用

    go语言基本类型 类型名称 有无符号 占用位数 int8 Yes 8 int16 Yes 16 int32 Yes 32 int64 yes 64 uint8 No 8 uint16 No 16 ui ...

  4. uintptr和unsafe.Pointer的区别

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

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

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

  6. golang reflect Pointer 获取 传入的interface信息

    使用反射可以获取到数据的类型信息,reflect.TypeOf()返回的数据类型如下: type rtype struct {size uintptrptrdata uintptr // number ...

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

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

  8. 深度解密Go语言之unsafe

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

  9. Golang: unsafe包的使用

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

最新文章

  1. springMvc的执行流程(源码分析)
  2. 读书笔记《数据挖掘概念与技术》第2章 数据预处理 2.4 数据集成和变换
  3. DOS命令温习(图解)
  4. 简单的基于hash和hashchange的前端路由
  5. 数学的列向量内积计算方法
  6. Android 违规使用 Java,谷歌或面临 88 亿美元赔款
  7. linux less从后向前查看日志信息
  8. 让子弹飞,零成本让你的网站更快一点,boxopened http/3 (QUIC) 协议实战
  9. C语言之数据类型,C语言之数据类型
  10. 树形dp 没有上司的舞会
  11. 2015 NI 校招笔试机试面试
  12. 运维自动化之ansible playbook安装mysql
  13. Jupyter Notebook打开时报错的问题解决办法
  14. 苹果设备解锁工具:iToolab UnlockGo for Mac
  15. Visio如何画箭头
  16. Laravel 代码开发最佳实践
  17. Mysql区分大小写问题
  18. 月薪过万是普遍现象吗?很抱歉,这事大部分人的错觉
  19. word中怎么把脚注转换为尾注
  20. 深度学习【23】图像风格化总结

热门文章

  1. ubuntu之sudo apt-get update提示Could not connect to 127.0.0.1:8081 (127.0.0.1)解决办法
  2. java.io.StreamCorruptedException: invalid type code: AC解决办法
  3. linux之tmp文件夹
  4. Android之滑动事件冲突解决 Touch事件处理机制总结
  5. Android之TextUtils类介绍
  6. eclipse myeclipse 快捷键
  7. java mysbatis select_MyBatis SELECT基本查询实现方法详解
  8. 螺丝刀还能悬浮起来?
  9. 这才是真正的,坐上来,自己动!| 今日趣图
  10. 入门Python,限时1元!