什么是内存对齐
CPU在访问内存的时候,并不是一个字节一个字节读取,而是以字长(word size)为单位访问。32位CPU字长为4字节,64位CPU字长是8字节。32CPU访问内存的时候只能以4的倍数的内存开始地址读取。如果一个变量存储在跨字长的内存区域上,CPU就需要多次访问内存才能读取。
Golang为了尽量避免这种跨字长的内存访问,在内存分配时会做一次内存对齐。
内存对齐示例
1 | type Foo struct { |
CPU在访问内存的时候,并不是一个字节一个字节读取,而是以字长(word size)为单位访问。32位CPU字长为4字节,64位CPU字长是8字节。32CPU访问内存的时候只能以4的倍数的内存开始地址读取。如果一个变量存储在跨字长的内存区域上,CPU就需要多次访问内存才能读取。
Golang为了尽量避免这种跨字长的内存访问,在内存分配时会做一次内存对齐。
1 | type Foo struct { |
反射是指程序在运行时检查、修改自身结构和行为的能力,极大的能加了程序的灵活性,有的时候反射能大量的减少冗余代码。反射是把双刃剑,提供强大的扩展能力是以牺牲性能为代价的,同时反射会使程序的逻辑更为复杂,降低了代码的可读性,所以在使用反射的时候一定要慎重。
大多数高级编程语言都提供了反射的功能,Golang通过reflect包提供了简洁、高效的反射功能
Golang反射功能比较简单,不支持从一个字符串来创建对象,所有的反射功能都是针对已有的对象,Golang反射功能把已有对象当做一个空interface
,所有的反射操作都在空interface
上。
Golang的反射功能都封装在了reflect
包中,该包提供了两个基本类型reflect.Type
, reflect.Value
,Golang的反射都是围绕这两个类型进行的。reflect.Type
是一个interface
,可以获取跟类型相关的信息。reflect.Value
是一个结构体,包含了数据相关的信息,可以对reflect.Value
进行修改,实现修改运行时数据的功能。
另外该包还提供了两个基本的方法reflect.TypeOf()
, reflect.ValueOf()
来获取以上两个基本类型
1 | a := 1 |