Golang结构体分析
来源:互联网 发布:多益网络加班严重吗 编辑:程序博客网 时间:2024/06/04 19:50
Golang结构体分析
学习golang有一段时间,本人是从c++转学golang的,因此想研究一下golang的结构体是否也像c++一样存在字节对齐的现象。测试代码如下:
// test project main.gopackage mainimport ( "fmt" "unsafe")type Test struct { i int b byte}type Test2 struct { b2 byte i2 int}func main() { var stTest = Test{ i: 1, b: 'a', } var stTest2 = Test2{ b2: 'a', i2: 1, } //获取Test结构体的大小,结果为16 ilen := unsafe.Sizeof(stTest) fmt.Println("stTest=", stTest, " sizeof=", ilen) //获取stTest.i的地址 var pI *int = (*int)(unsafe.Pointer(&stTest)) //修改stTest.i的值为3 *pI = int(3) //获取stTest.b的地址 var pB *byte = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest)) + uintptr(unsafe.Sizeof(int(0))))) //将stTest.b的值修改为'c' *pB = byte('c') fmt.Println("after change stTest=", stTest) //获取stTest.b在结构体中的偏移量 offset := unsafe.Offsetof(stTest.b) fmt.Println("stTest.b offset=", offset) //获取Test2结构体的大小,结果为16 ilen = unsafe.Sizeof(stTest2) fmt.Println("stTest2=", stTest2, " sizeof=", ilen) //获取stTest2.b2的地址 var pB2 *byte = (*byte)(unsafe.Pointer(&stTest2)) //重新设置stTest2.b2的值为'c' *pB2 = byte('c') //var pI2 *int = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest2)) + uintptr(unsafe.Sizeof(byte('a'))))) //获取stTest2.i2的地址 var pI2 *int = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest2)) + unsafe.Offsetof(stTest2.i2))) //重新设置stTest2.i2的值为3 *pI2 = int(3) fmt.Println("after change stTest2=", stTest2) offset = unsafe.Offsetof(stTest2.i2) fmt.Println("stTest2.i2 offset=", offset)}
最后输出的结果如下:
stTest= {1 97} sizeof= 16
after change stTest= {3 99}
stTest.b offset= 8
stTest2= {97 1} sizeof= 16
after change stTest2= {99 3}
stTest2.i2 offset= 8
ilen := unsafe.Sizeof(stTest)获取的结构体大小是16 说明存在字节对齐的现象8(i大小)+1(b大小)+7字节(补充字节)
var pB *byte = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest)) + uintptr(unsafe.Sizeof(int(0)))))
这段代码是存在一定问题的,它的作用是将stTest的地址+stTest.i的大小(注意是大小而不是stTest.b的偏移量),如果结构体中第一个元素存在补位的情况结果就不正确
结构体Test2就是用来测试第一个元素存在补位的情况,如果将注释的那段代码
var pI2 *int = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest2)) + uintptr(unsafe.Sizeof(byte(‘a’)))))
替换
var pI2 *int = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&stTest2)) + unsafe.Offsetof(stTest2.i2)))
那么stTest2的结果将不能被正确的重置,得到stTest2的结果将是
after change stTest2= {99 0}
通过分析stTest2= {97 1} sizeof= 16和stTest2.i2 offset= 8我们可以得出stTest2.b2占用了8个字节,但是b2是一个byte类型,它的大小是1个字节,这说明了b2后还补了7个字节用于字节对齐
- Golang结构体分析
- golang初始化结构体
- golang: 常用数据类型底层结构分析
- golang: 常用数据类型底层结构分析
- 原 golang 结构体
- Golang json转结构体
- Golang结构体和指针
- Rust golang之结构体
- Golang从入门到精通(十四):Golang结构体
- 跟着猫哥学Golang[6] - 结构体
- golang 动态 实例化 结构体
- Golang中结构体转byte数组
- Golang学习笔记 结构体和指针
- golang中结构体转成xml格式
- Golang教程:(十六)结构体
- golang 空结构体struct{}解析
- golang结构体struct学习笔记
- Golang语言社区--结构体数据排序
- Linux和Mysql创建用户及授权方法与C连接Mysql的方法
- 多线程并发执行任务,取结果归集。终极总结:Future、FutureTask、CompletionService、CompletableFuture
- STM32F429 使用 TCS34725 颜色传感器的驱动程序
- 基于CMake 在Android studio2.2+ 中开发JNI
- Configuring the Hive Metastore for CDH
- Golang结构体分析
- Java实现分段视频合并
- Monthly Expense
- 使用MyEclipse发布Web项目时URL访问路径问题。
- mysql配置
- 如何读写csv数据
- WebView的使用详解
- java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList
- ElasticSearch学习(2)--使用Kibana连接ES(5.0以上版本)