Go unsafe Pointer
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
的四个原则:
- 任何指针都可以转换为
unsafe.Pointer
;unsafe.Pointer
可以转换为任何指针;uintptr
可以转换为unsafe.Pointer
;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相关推荐
- Golang unsafe.Pointer指针
相较于 C 而言,Go 语言在设计时为了使用安全给指针在类型和运算上增加了限制,这让Go程序员既可以享受指针带来的便利,又避免了指针的危险性.除了常规的指针外,Go 语言在 unsafe 包里其实还通 ...
- Go 指针 unsafe.Pointer
Go语言是个强类型语言.也就是说Go对类型要求严格,不同类型不能进行赋值操作.指针也是具有明确类型的对象,进行严格类型检查.下面的代码会产生编译错误 : package main import (&q ...
- 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 ...
- uintptr和unsafe.Pointer的区别
unsafe.Pointer其实就是类似C的void *,在golang中是用于各种指针相互转换的桥梁.uintptr是golang的内置类型,是能存储指针的整型,uintptr的底层类型是int,它 ...
- Go 学习笔记(74)— Go 标准库之 unsafe
Go 语言自带的 unsafe 包的高级用法, 顾名思义,unsafe 是不安全的.Go 将其定义为这个包名,也是为了让我们尽可能地不使用它.不过虽然不安全,它也有优势,那就是可以绕过 Go 的内存安 ...
- golang reflect Pointer 获取 传入的interface信息
使用反射可以获取到数据的类型信息,reflect.TypeOf()返回的数据类型如下: type rtype struct {size uintptrptrdata uintptr // number ...
- runtime error: invalid memory address or nil pointer dereference
runtime error: invalid memory address or nil pointer dereference 解决方法: tcallback((unsigned char*)pac ...
- 深度解密Go语言之unsafe
上一篇文章我们详细分析了 map 的底层实现,如果你也跟着阅读了源码,那一定对 unsafe.Pointer 不陌生,map 对 key 进行定位的时候,大量使用. unsafe.Pointer 位于 ...
- Golang: unsafe包的使用
1. golang各类型占空间字节数 package mainimport ("fmt""unsafe" )var tByte byte var tRune r ...
最新文章
- springMvc的执行流程(源码分析)
- 读书笔记《数据挖掘概念与技术》第2章 数据预处理 2.4 数据集成和变换
- DOS命令温习(图解)
- 简单的基于hash和hashchange的前端路由
- 数学的列向量内积计算方法
- Android 违规使用 Java,谷歌或面临 88 亿美元赔款
- linux less从后向前查看日志信息
- 让子弹飞,零成本让你的网站更快一点,boxopened http/3 (QUIC) 协议实战
- C语言之数据类型,C语言之数据类型
- 树形dp 没有上司的舞会
- 2015 NI 校招笔试机试面试
- 运维自动化之ansible playbook安装mysql
- Jupyter Notebook打开时报错的问题解决办法
- 苹果设备解锁工具:iToolab UnlockGo for Mac
- Visio如何画箭头
- Laravel 代码开发最佳实践
- Mysql区分大小写问题
- 月薪过万是普遍现象吗?很抱歉,这事大部分人的错觉
- word中怎么把脚注转换为尾注
- 深度学习【23】图像风格化总结
热门文章
- ubuntu之sudo apt-get update提示Could not connect to 127.0.0.1:8081 (127.0.0.1)解决办法
- java.io.StreamCorruptedException: invalid type code: AC解决办法
- linux之tmp文件夹
- Android之滑动事件冲突解决 Touch事件处理机制总结
- Android之TextUtils类介绍
- eclipse myeclipse 快捷键
- java mysbatis select_MyBatis SELECT基本查询实现方法详解
- 螺丝刀还能悬浮起来?
- 这才是真正的,坐上来,自己动!| 今日趣图
- 入门Python,限时1元!