教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 11.深入理解切片(slice)

11.深入理解切片(slice)

发布时间:2022-03-05   编辑:jiaochengji.com
教程集为您提供11.深入理解切片(slice)等资源,欢迎您收藏本站,我们将为您提供最新的11.深入理解切片(slice)资源
<h1>本文视频地址</h1>

slice是 Go 语言在数组之上提供的一个重要的抽象数据类型。在绝大多数需要使用数组的场合,切片都实现了完美替代。并且和数组相比,切片提供了更通用、功能更强大且便捷的数据序列访问接口。

<h1>1.什么是数组</h1>

Go 语言数组是一个固定长度的、容纳同构类型元素的连续序列。因此 Go 数组类型具有两个属性:元素类型和数组长度。但凡这两个属性相同的数组类型是等价的。比如下面变量 a、b、c 对应的数组类型是三个不同的数组类型:

<pre><code class="lang-go hljs">var a [8]string var b [8]byte var c [9]string</code></code></pre>

变量 a、b 对应的数组类型长度属性相同,但元素类型不同,a是string,b是byte.
变量 a、c 对应的数组类型的元素类型相同,都是 int,但数组类型的长度不(a是 8,c是 9)

Go 的数组是值类型,这点和JAVA完全不同。在JAVA中数组是引用类型。在Go语言中,传递数组是纯粹的值拷贝。

<h1>2.切片究竟是什么</h1>

在 Go 语言中,数组更多是底层存储空间的角色;而切片是为底层的数组打开了一个访问的“窗口”。下面看一下切片的源代码

<pre><code class="lang-go hljs">//$GOROOT/src/runtime/slice.go type slice struct { array unsafe.Pointer len int cap int } array:是指向下层数组某元素的指针,该元素也是切片的起始元素; len:是切片的长度,即切片中当前元素的个数; cap:是切片的最大容量,cap >= len;</code></code></pre>

在运行时中,每个切片变量都是一个 runtime.slice 结构体的实例。
创建一个 slice 实例:s1 := make([]byte, 5),编译器会自动为切片建立一个底层数组,如果没有在 make 中指定 cap 参数,那么 cap = len。

我们还可以创建对已存在数组进行操作的切片,语法 u[low:max] :
u := [10]byte{10, 12, 23, 14, 15, 16, 17, 88, 69, 20}
s := u[3:7]
切片是 [14 15 16 17]
通过 s 看到的第一个元素是 u[3],我们通过 s 能看到并操作的数组元素是 4 个(max-low)。切片的 cap 值取决于底层数组的长度。我们看到从切片 s 的第一个元素 s[0],即 u[3] 到数组末尾一共有 7 个元素,因此切片 s 的 cap 为 7。

当切片作为函数参数传递给函数时,实际传递的就是切片的内部表示,也就是上面的 runtime.slice 结构体实例,因此无论切片“描述”的底层数组有多大,切片作为参数传递带来的性能损耗都是小到可以忽略不计的。这就是为什么函数在参数中多使用切片而不用数组指针的原因之一。

<h1>3. 切片的高级特性:动态扩容</h1><pre><code class="lang-go hljs">var s []int // s被赋予零值nil s = append(s, 1) </code></code></pre>

由于初值为零值,s 这个“描述符”并没有绑定对应的底层数组。而经过 append 操作后,s 显然已经“绑定”了属于它的底层数组。

append 会根据 slice 对底层数组容量的需求对底层数组进行动态调整。 append在当前底层数组容量无法满足的情况下,动态分配新的数组,新数组长度会按一定规律扩展(这里针对元素是 int 型的数组,新数组的容量为当前数组的 2 倍。其他类型的扩展系数可能有所不同),新数组建立后,append 会把旧数组中的数据 copy 到新数组中,之后新数组便成为了 slice 的底层数组,旧数组会被垃圾回收掉。

<h1>4. 尽量使用 cap 参数创建 slice</h1>

s := make([]T, 0, cap)
这样会避免扩容带来的性能开销,如果可以预估出切片底层数组需要承载的元素数量,强烈建议在创建 slice 时带上 cap 参数。

<span class="img-wrap"></span>


到此这篇关于“11.深入理解切片(slice)”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Go语言之父详述切片与数组的不同
11.深入理解切片(slice)
Go解密:数组、切片
深度解密Go语言之Slice
切片 里面包含interface_Golang数据结构详解之切片
Golang 深入 slice 实现原理及使用技巧
golang slice 最后一个元素_Go 常见的数据结构 Slice
深入理解go的slice和到底什么时候该用slice
饶全成:汇编角度看 Slice,一个新的世界
【Go语言】【7】GO语言的切片

上一篇:08.无类型常量 下一篇:12.Go字符串
[关闭]
~ ~