美文网首页
GO基础学习笔记(3)结构体

GO基础学习笔记(3)结构体

作者: 温岭夹糕 | 来源:发表于2022-07-31 19:36 被阅读0次

导读

空结构体

var a struct{}
fmt.Println(unsafe.Sizeof(a)) //0
很奇怪,空指针按常理来说怎么都是个整数类型的指针,怎么会不占用空间呢?更奇怪的是,我们用dlv工具也打不上断点(var a struct{}),go tool compile -S main.go | grep "main.go:" 发现根本没有这行代码对应的汇编,直接被优化掉了(没有main.go:8) image.png

仔细想想也是,既然不占用内存直接连寄存器存值都没必要
我们去之前分配内存的函数mallocgc看一下,发现这么一行代码


image.png
如果size=0那么就返回一个zerobase的地址
// base address for all 0-byte allocations
var zerobase uintptr

看这变量的注解恍然大悟,所有的零比特(这里空结构体)内存都是指向这个地址。
那么我们基于内存零开销就能做很多事情了,比如当作信号传入channel,与map结合实现set即值没有意义,只需要键

继承?嵌入字段!

go没有继承的概念,把结构体a当作结构体b成员,结构体b也能调用a的方法,甚至只需要提供类型就可以(这叫做嵌入字段)

type Person struct{}

func (p Person) say() {
        fmt.Println("hi")
}

type Book struct{ 
        Person
}

func main() {
        var a = Book{}
        a.say() // "hi"
}

内存布局

内存大小与数组一样仅仅是简单的成员大小相加?不是的,但是结构体的内存是非常紧凑的,我们要知道一个前提,计算机读取数据是以字长为单位的(我以8字节的字长系统为例),那么我们就要确保我们要读取的变量刚好在这个字长的整数倍范围内,不能东一块西一块,不然不好拼接,以结构体T为例

type T  struct{
a  int8
b  string  //16
}

如果我们是紧挨着排列会怎么样

image.png
第一次按字长读取a能读到,b不完整只读取了一部分,那剩下的部分要占1+1/8个字长,读完后还要切分拼接那效率多低(跨字长的排布会影响内存原子性和效率),我们需要把b的开头移到下一个字长,读b的时候连续读取2个字长不就效率更高了。其实a,b在字长这个区间上到底占哪一个是受对齐系数影响的
unsafe.Alignof()返回一个整数

变量的内存地址必须被对齐系数整除,string的对齐系数为8,必须在8的倍数上,这是为了内存对齐,那结构体的成员顺序不就影响了内存大小(结构体的对齐系数为成员最大的对齐系数)

空结构体成员怎么办?

对齐系数是1,意味着可以随便放?
不是的,在结构体中意味着占位,大小会与前一个相同(前提是不是最后一个)
那放在最后呢

type A struct{
a int8
b struct{}
c string                                                                                                         
}                                                                                                                
                                                                                                                 
                                                                                                                 
type B struct {                                                                                                  
a int8                                                                                                           
b string                                                                                                         
c struct{}                                                                                                       
}                                                                                                                
                                                                                                                 
func main() {                                                                                                    
        var a A                                                                                                  
        var b B                                                                                                  
        fmt.Println(unsafe.Sizeof(a),unsafe.Alignof(a))                                                          
        fmt.Println(unsafe.Sizeof(b),unsafe.Alignof(b))                                                          
} 

24 8
32 8

占了32个字节,意味着最后的空结构体要占位,占满一个字长

interface

感觉没啥好讲的,跳过了

小结

所以在结构体中一定要注意字段的顺序,降低对空间的占用

参考

1.ref
2.Why is there no type inheritance?

相关文章

  • GO基础学习笔记(3)结构体

    导读 空结构体 很奇怪,空指针按常理来说怎么都是个整数类型的指针,怎么会不占用空间呢?更奇怪的是,我们用dlv工具...

  • Go学习笔记-结构体

    如果说 Go 语言的基础类型是原子,那么结构体就是分子。分子是原子的组合,让形式有限的基础类型变化出丰富多样的形态...

  • protoc-生成go指针

    protoc-生成go指针 这里指的是为结构体中基础类型生成go指针,嵌套结构体默认就是指针 为什么需要生成指针?...

  • Go语言探索 - 10(原创)

    上一篇文章主要学习了Go语言的结构体以及结构体指针,本篇文章主要学习Go语言的切片以及Map。 Go语言数组的长度...

  • Go学习--结构体

    结构体 1、结构体的定义: type n...

  • 15 Go结构体

    1、结构体基础 2、结构体之间的转换 3、匿名属性 4、结构体嵌套 5、结构体匿名属性注意点

  • Go语言基础语法--注释、基础结构2

    章节 GO语言基础语法--注释、基础结构(重要) 1.GO语言基础语法---注释、基础结构 基础结构注意事项 源文...

  • Go 学习笔记 08 | 结构体详解

    一、结构体 实例化结构体 第一种实例化结构体:var 变量 结构体 输出: 结构体首字母可以大写也可以小写,大写表...

  • go学习笔记(4) - 结构体、接口

    结构体与方法 工厂函数返回局部变量地址 结构体专有方法 结体构综合示例 接口 问题集锦 new与make new只...

  • go http学习笔记

    go http学习笔记 @[goweb, go, http] 1.go http基础 go http服务器简例 h...

网友评论

      本文标题:GO基础学习笔记(3)结构体

      本文链接:https://www.haomeiwen.com/subject/okphwrtx.html