golang基础数据类型深度解析

TangYiMo · · 1910 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

# Go 语言数据类型: 在 Go 编程语言中,数据类型用于声明函数、参数、返回值、定义变量,学习编程语言的基础就是把数据类型的基础理解清楚,本节课精心准备图文对golang数据类型分析(这篇文章是我录制的视频课程里面的一节课件,本着传播知识的精神发出来到博客中)。 **1、基础数据类型:** | 序号 | 类型和描述 | | :--- | :----------------------------------------------------------- | | 1 | **布尔型** 布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。 | | 2 | **数字类型** 整型 和 浮点型 | | 3 | **字符串类型:** 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本。 | | 4 | **派生类型:** 包括:(a) 指针类型(Pointer)(b) 数组类型(c) 结构化类型(struct)(d) 函数类型(e) 切片类型(f) 接口类型(interface) | *bool型:* > bool,值为true或false *整型:* Go 也有基于架构的类型,例如:int、uint 和 uintptr。 > **uint8** 无符号 8 位整型 (0 到 255)、**uint16** 无符号 16 位整型 (0 到 65535)、**uint32** 无符号 32 位整型 (0 到 4294967295)、**uint64** 无符号 64 位整型 (0 到 18446744073709551615)、**int8** 有符号 8 位整型 (-128 到 127)、**int16** 有符号 16 位整型 (-32768 到 32767)、**int32** 有符号 32 位整型 (-2147483648 到 2147483647)、**int64** 有符号 64 位整型 (-9223372036854775808 到 9223372036854775807) *浮点型:* > **float32** IEEE-754 32位浮点型数、**float64** IEEE-754 64位浮点型数、**complex64** 32 位实数和虚数、**complex128** 64 位实数和虚数 *派生类型:* > var pint *int > > var pbool *bool > > var c1 chan string > > var slice []int64 *其他数字类型* > **byte** 类似 uint8、**rune** 类似 int32、**uint** 32 或 64 位、**int** 与 uint 一样大小、**uintptr** 无符号整型,用于存放一个指针 ----- **2、复合数据类型:** | 序号 | 类型和描述 | | :--- | :----------------------------------------------------------- | | 1 | **数组** 数组类型是一片size固定的内存区域 | | 2 | **slice切片** 切片类型是一片size可变的内存区域 | | 3 | **Map** map是哈希表的引用,map类型可以写为map[K]V,其中K和V分别对应key和value。map中所有的key都有相同的类型,所有的value也有着相同的类型,但是key和value之间可以是不同的数据类型。key必须是支持==算数\|逻辑运算的数据类型 | | 4 | **结构体:** 结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员 | | 5 | **channel:** channel类型是golang携程之间线程安全通讯的机制。 | ------ ### 数组类型: > 数组类型不能动态扩容,其它用法与slice比较相似,其内部结构参照slice类型的结构。 ### slice类型: slice由header和body组成。header有3个变量组成:指针、实际数据长度、内存区域最大容量。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210711114846503.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210711114914608.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) 举个例子: slice:= make(int[], 4, 6) 创建一个长度为4,容量为6的int类型slice,如下图: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TWcjxaLH-1625975123089)(C:\Users\Admin\Desktop\datatype\icon\slice3.png)\]](https://img-blog.csdnimg.cn/20210711114954366.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) slice在语言包中的定义: ```go type slice struct { array unsafe.Pointer len int cap int } ``` 创建切片: ```go func makeslice(et *_type, len, cap int) slice { p := mallocgc(et.size*uintptr(cap), et, true) return slice{p, len, cap} } ``` 根据容量cap*元素size,申请一块内存。`mallocgc`大空间(大于32kb)才会在heap堆上申请,否则在栈上分配。切片的底层就是一片指针指向的内存,也可以看作是一个动态(可以扩容的)数组。 切片扩容: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NC8fLj8R-1625975123091)(C:\Users\Admin\Desktop\datatype\icon\slice4.png)\]](https://img-blog.csdnimg.cn/20210711115045138.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) ```go // slice 扩容伪代码: { newcap := old.cap doublecap := newcap + newcap if cap > doublecap { newcap = cap } else { if old.len < 1024 { newcap = doublecap } else { for newcap < cap { newcap += newcap / 4 } } } // 如果容量有扩容,则申请信的内存区域、把旧数据从老的内存区域 copy 到新申请的内存区域、将array 指向新申请的内存区域、标记旧的内存区域可被回收 等待gc回收 } ``` cap增长的策略: 1. 如果期望大于double,新cap就等于期望; 2. 如果当前大小小于1024,则两倍增长; 3. 否则每次增长25%,直到满足期望。 ### map类型: ```go // A header for a Go map. type hmap struct { // 元素个数,调用 len(map) 时,直接返回此值 count int flags uint8 B uint8 // buckets 的对数 log_2 // overflow 的 bucket 近似数 noverflow uint16 // 计算 key 的哈希的时候会传入哈希函数 hash0 uint32 buckets unsafe.Pointer // 指向内存的指针,可以看作是:[]bmap。 其大小为 2^B. 如果元素个数为0,就为 nil // 扩容的时候,buckets 长度会是 oldbuckets 的两倍 oldbuckets unsafe.Pointer // 指示扩容进度,小于此地址的 buckets 迁移完成 nevacuate uintptr extra *mapextra // optional fields } // buckets指向的结构体 type bmap struct { tophash [bucketCnt]uint8 // bucketCnt值固定为8个,也就是每个bmap最大能存储8个key-value对。 } // go编译器在编译时,会扩展bmap为如下的结构: type bmap struct { topbits [8]uint8 keys [8]keytype values [8]valuetype pad uintptr overflow uintptr } ``` map结构图: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1HMD53of-1625975123092)(C:\Users\Admin\Desktop\datatype\icon\map.png)\]](https://img-blog.csdnimg.cn/20210711115126322.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) 例如:m1 map[string]string插入一条数据的过程如下: > insert "key1 name":"乔布斯" > > hashvalue = hash("key1 name") > > slot = hashvalue的低8bit % len(m1),例如m1的槽位是4个,则slot = hashvalue % 4。假设slot = 2 > > hashvalue的高8bit这条数据应该插入到bmap中的第几个子槽。如果bmap已经写满8个,则读取overflow指向的下一个紧邻着的bmap去插入这条数据 注意:bmap中k-v的存放方式是:key0、key1、key2、key3、key4、key5、key6、key7、val0、val1、val2、val3、val4、val5、val6、val7、pads、overflow (我认为改成叫next更为合适) ### 结构体: > 结构体类型,是基本数据类型和派生类型的组合。与其它编程语言的结构体在组成上面差不多。但是引用与其它有一定的差异,会在interface和对象继承等章节穿插讲。 ### channel类型: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RiQZDBJb-1625975123094)(C:\Users\Admin\Desktop\datatype\icon\channel.png)\]](https://img-blog.csdnimg.cn/20210711115157111.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70) > channel 本质只是一个环形队列,有读、写索引、有互斥锁。 能够及时通知go调度器对读写channel的go routine进行调度。 ### channel写入数据: ![\[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VZKEeJUl-1625975123094)(C:\Users\Admin\Desktop\datatype\icon\channel-send.png)\]](https://img-blog.csdnimg.cn/20210711115214639.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2phY2t5MTI4MjU2,size_16,color_FFFFFF,t_70)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1910 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传