go语言的切片 go语言切片初始化

go语言中实现切片(slice)的三种方式定义一个切片,然后让切片去引用一个已经创建好的数组 。基本语法如下:
索引1:切片引用的起始元素位
索引2:切片只引用该元素位之前的元素
例程如下:
在该方法中,我们未指定容量cap,这里的值为5是系统定义的 。
在方法一中,可以用arr数组名来操控数组中的元素,也可以通过slice切片来操控数组中的元素 。切片是直接引用数组,数组是事先存在的,程序员是可见的 。
通过 make 来创建切片 , 基本语法如下:
make函数第三个参数cap即容量是可选的,如果一定要自己注明的话,要注意保证cap≥len 。
用该方法可以 指定切片的大小(len)和容量(cap)
例程如下:
由于未赋值系统默认将元素值置为0 , 即:
数值类型数组:默认值为 0
字符串数组:默认值为 ""
bool数组:默认值为 false
在方法二中,通过make方式创建的切片对应的数组是由make底层维护,对外不可见 , 即只能通过slice去访问各个元素 。
定义一个切片,直接就指定具体数组 , 使用原理类似于make的方式 。
例程如下:
Go语言 排序与搜索切片Go语言标准库中提供go语言的切片了sort包对整型go语言的切片,浮点型go语言的切片 , 字符串型切片进行排序go语言的切片,检查一个切片是否排好序go语言的切片,使用二分法搜索函数在一个有序切片中搜索一个元素等功能 。
关于sort包内的函数说明与使用 , 请查看
在这里简单讲几个sort包中常用的函数
在Go语言中,对字符串的排序都是按照字节排序,也就是说在对字符串排序时是区分大小写的 。
二分搜索算法
Go语言中提供了一个使用二分搜索算法的sort.Search(size,fn)方法:每次只需要比较㏒?n个元素 , 其中n为切片中元素的总数 。
sort.Search(size,fn)函数接受两个参数:所处理的切片的长度和一个将目标元素与有序切片的元素相比较的函数,该函数是一个闭包 , 如果该有序切片是升序排列,那么在判断时使用 有序切片的元素 = 目标元素 。该函数返回一个int值 , 表示与目标元素相同的切片元素的索引 。
在切片中查找出某个与目标字符串相同的元素索引
Golang 中数组(Array)和切片(Slice)的区别 Go 中数组go语言的切片的长度是不可改变的go语言的切片,而 Slice 解决的就是对不定长数组的需求 。他们的区别主要有两点 。
数组:
切片:
注意 1
虽然数组在初始化时也可以不指定长度,但 Go 语言会根据数组中元素个数自动设置数组长度 , 并且不可改变 。切片通过 append 方法增加元素:
如果将 append 用在数组上,go语言的切片你将会收到报错:first argument to append must be slice 。
注意 2
切片不只有长度(len)的概念,同时还有容量(cap)的概念 。因此切片其实还有一个指定长度和容量的初始化方式:
这就初始化go语言的切片了一个长度为3,容量为5的切片 。
此外,切片还可以从一个数组中初始化(可应用于如何将数组转换成切片):
上述例子通过数组 a 初始化了一个切片 s 。
当切片和数组作为参数在函数(func)中传递时 , 数组传递的是值,而切片传递的是指针 。因此当传入的切片在函数中被改变时 , 函数外的切片也会同时改变 。相同的情况,函数外的数组则不会发生任何变化 。
GoLang中的切片扩容机制[5]int是数组,而[]int是切片 。二者看起来相似 , 实则是根本上不同的数据结构 。
切片的数据结构中,包含一个指向数组的指针array , 当前长度len,以及最大容量cap。在使用make([]int, len)创建切片时,实际上还有第三个可选参数cap , 也即make([]int, len, cap)。在不声明cap的情况下,默认cap=len。当切片长度没有超过容量时,对切片新增数据 , 不会改变array指针的值 。
当对切片进行append操作,导致长度超出容量时,就会创建新的数组 , 这会导致和原有切片的分离 。在下例中
由于a的长度超出了容量,所以切片a指向了一个增长后的新数组,而b仍然指向原来的老数组 。所以之后对a进行的操作,对b不会产生影响 。
试比较
本例中,a的容量为6 , 因此在append后并未超出容量,所以array指针没有改变 。因此,对a进行的操作 , 对b同样产生了影响 。
下面看看用a := []int{}这种方式来创建切片会是什么情况 。
可以看到,空切片的容量为0,但后面向切片中添加元素时 , 并不是每次切片的容量都发生了变化 。这是因为,如果增大容量,也即需要创建新数组 , 这时还需要将原数组中的所有元素复制到新数组中,开销很大,所以GoLang设计了一套扩容机制 , 以减少需要创建新数组的次数 。但这导致无法很直接地判断append时是否创建了新数组 。
如果一次添加多个元素,容量又会怎样变化呢?试比较下面两个例子:
那么 , 是不是说,当向一个空切片中插入2n-1个元素时,容量就会被设置为2n呢?我们来试试其他的数据类型 。
可以看到,根据切片对应数据类型的不同,容量增长的方式也有很大的区别 。相关的源码包括: src/runtime/msize.go , src/runtime/mksizeclasses.go 等 。
我们再看看切片初始非空的情形 。
可以看到,与刚刚向空切片添加5个int的情况一致,向有3个int的切片中添加2个int , 容量增长为6 。
需要注意的是,append对切片扩容时,如果容量超过了一定范围,处理策略又会有所不同 。可以看看下面这个例子 。
具体为什么会是这样的变化过程,还需要从 源码 中寻找答案 。下面是src/runtime/slice.go中的growslice函数中的核心部分 。
GoLang中的切片扩容机制,与切片的数据类型、原本切片的容量、所需要的容量都有关系,比较复杂 。对于常见数据类型 , 在元素数量较少时,大致可以认为扩容是按照翻倍进行的 。但具体情况需要具体分析 。
【go语言的切片 go语言切片初始化】go语言的切片的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言切片初始化、go语言的切片的信息别忘了在本站进行查找喔 。

    推荐阅读