教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang语言slice实现原理及使用方法

Golang语言slice实现原理及使用方法

发布时间:2021-12-16   编辑:jiaochengji.com
教程集为您提供Golang语言slice实现原理及使用方法等资源,欢迎您收藏本站,我们将为您提供最新的Golang语言slice实现原理及使用方法资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg><h1>1. Slice实现原理</h1>

Slice依托数组实现,底层数组对用户屏蔽,在底层数组容量不足时可以实现自动重分配并生成新的Slice。 接下来按照实际使用场景分别介绍其实现机制。

源码包中src/runtime/slice.go:slice定义了Slice的数据结构:

<pre><code class="lang-go hljs"><span class="token keyword">type</span> slice <span class="token keyword">struct</span> <span class="token punctuation">{</span> array unsafe<span class="token punctuation">.</span>Pointer <span class="token builtin">len</span> <span class="token builtin">int</span> <span class="token builtin">cap</span> <span class="token builtin">int</span> <span class="token punctuation">}</span> </code></pre>

从数据结构看Slice很清晰, array指针指向底层数组,len表示切片长度,cap表示底层数组容量。

<h1>
2. Slice的使用方法</h1> <h2>2.1 使用make创建Slice</h2>

使用make来创建Slice时,可以同时指定长度和容量,创建时底层会分配一个数组,数组的长度即容量。
例如,语句slice := make([]int, 5, 10)所创建的Slice,结构如下图所示:

该Slice长度为5,即可以使用下标slice[0] ~ slice[4]来操作里面的元素,capacity为10,表示后续向slice添加新的元素时可以不必重新分配内存,直接使用预留内存即可。

<h2>
2.2 使用数组创建Slice</h2>

使用数组来创建Slice时,Slice将与原数组共用一部分内存。

例如,语句slice := array[5:7]所创建的Slice,结构如下图所示:

切片从数组array[5]开始,到数组array[7]结束(不含array[7]),即切片长度为2,数组后面的内容都作为切片的预留内存,即capacity为5。
数组和切片操作可能作用于同一块内存,这也是使用过程中需要注意的地方。

<h2>
2.3 Slice 扩容</h2>

使用append向Slice追加元素时,如果Slice空间不足,将会触发Slice扩容,扩容实际上是重新分配一块更大的内存,将原Slice数据拷贝进新Slice,然后返回新Slice,扩容后再将数据追加进去。

例如,当向一个capacity为5,且length也为5的Slice再次追加1个元素时,就会发生扩容,如下图所示:

扩容操作只关心容量,会把原Slice数据拷贝到新Slice,追加数据由append在扩容结束后完成。上图可见,扩容后新的Slice长度仍然是5,但容量由5提升到了10,原Slice的数据也都拷贝到了新Slice指向的数组中。

扩容容量的选择遵循以下规则:

<ul><li>如果原Slice容量小于1024,则新Slice容量将扩大为原来的2倍</li><li>如果原Slice容量大于等于1024,则新Slice容量将扩大为原来的1.25倍</li></ul>

使用append()向Slice添加一个元素的实现步骤如下:

<ul><li>假如Slice容量够用,则将新元素追加进去,Slice.len ,返回原Slice</li><li>原Slice容量不够,则将Slice先扩容,扩容后得到新Slice;将新元素追加进新Slice,Slice.len ,返回新的Slice。</li></ul><h2>
2.4 注意事项</h2> <ul><li>创建切片时可根据实际需要预分配容量,尽量避免追加过程中扩容操作,有利于提升性能</li><li>切片拷贝时需要判断实际拷贝的元素个数</li><li>谨慎使用多个切片操作同一个数组,以防读写冲突</li><li>使用append()向切片追加元素时有可能触发扩容,扩容后将会生成新的切片</li></ul><blockquote>

参考:《GO专家编程》

</blockquote> 到此这篇关于“Golang语言slice实现原理及使用方法”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang语言slice实现原理及使用方法
想系统学习GO语言(Golang
[go语言]-slice实现的使用和基本原理
理解 Go 编程中的 slice
学习golang开始前的准备工作
golang key map 所有_Golang面试知识点总结
【Golang】01 Go 语言初识
Go 语言的核心优势
go语言有哪些优势?Go语言的核心特性有哪些
Go如何对数组切片进行去重

[关闭]
~ ~