数组&切片

数组

1.语法

数组长度也是数组类型的一部分,所以[5] int[10] int是属于不同类型的,如果想让数组元素类型为任意类型的话可以使用空接口作为类型,数组长度最大为2Gb

var identifier [len]type

2.Go 语言中的数组是一种 值类型(不像 C/C++ 中是指向首元素的指针),所以可以通过 new() 来创建: var arr1 = new([5]int)

var arr1 = new([5]int) //arr1类型是 *[5]int
var arr2 = [5]int //arr2类型是 [5]int

切片

基础用法
  1. 切片(slice)是对数组一个连续片段的引用(该数组我们称之为相关数组,通常是匿名的),所以切片是一个引用类型

  2. 切片是可索引的,并且可以由 len() 函数获取长度。

  3. 给定项的切片索引可能比相关数组的相同元素的索引小。和数组不同的是,切片的长度可以在运行时修改,最小为 0 最大为相关数组的长度 总结:切片是一个长度可变的数组。

  4. 多个切片如果表示同一个数组的片段,它们可以共享数据;因此一个切片和相关数组的其他切片是共享存储的,相反,不同的数组总是代表不同的存储。数组实际上是切片的构建块

  5. 切片提供了计算容量的函数 cap() 可以测量切片最长可以达到多少:它等于切片从第一个元素开始,到相关数组末尾的元素个数,切片的长度永远不会超过它的容量

  6. 注意:绝对不要用指针指向 slice。切片本身已经是一个引用类型,所以它本身就是一个指针

  7. 切片只能向后移动s2 = s2[1:](s2为切片)

语法:

var identifier []type //声明不需要指明长度,未初始化之前默认为 nil,长度为 0
var slice1 []type = arr1[start:end] //初始化
var slice1 []type = arr1[: //取完整数组切片
slice = &arr //这也是切片,aar是一个数组
s = s[:cap(s)] //拓展大小上限

切片在内存中的组织方式实际上是一个有 3 个域的结构体:指向相关数组的指针,切片长度以及切片容量

使用make()创建一个切片

make([]type,len,cap) //cap可选
make([]int, 50, 100) //make和new生成的切片相同
new([100]int)[0:50]
  • new(T) 为每个新的类型 T 分配一片内存,初始化为 0 并且返回类型为 * T 的内存地址:这种方法 返回一个指向类型为 T,值为 0 的地址的指针,它适用于值类型如数组和结构体,它相当于 &T{}
  • make(T) 返回一个类型为 T 的初始值,它只适用于 3 种内建的引用类型:切片、map 和 channel

换言之,new 函数分配内存,make 函数初始化;下图给出了区别

通过分片的分片(或者切片的数组),长度可以任意动态变化,所以 Go 语言的多维切片可以任意切分。而且,内层的切片必须单独分配(通过 make 函数)

切片的复制和追加
package main
import "fmt"
func main() {
sl_from := []int{1, 2, 3}
sl_to := make([]int, 10)
n := copy(sl_to, sl_from) //copy返回拷贝的元素数量
fmt.Println(sl_to)
fmt.Printf("Copied %d elements\n", n) // n == 3
sl3 := []int{1, 2, 3}
sl3 = append(sl3, 4, 5, 6)
fmt.Println(sl3)
}

把切片y追加到切片x上:x = append(x, y...)

append函数非常有用,通过append函数的组合使用可以表示任意可便长度的序列

字符串、数组和切片的应用

注:字符串的本质是一个字节数组,所以关于切片的操作都可以用在字符串上,例如上面copyappend函数的源目标也可以是一个字符串

在内存中,一个字符串实际上是一个双字结构,即一个指向实际数据的指针和记录字符串长度的整数。因为指针对用户来说是完全不可见,因此我们可以依旧把字符串看做是一个值类型,也就是一个字符数组。Go中字符串是不可改变的,语句str[i]='D'会报错。对于字符串的修改都是建立在切片上(或者是byte数组)的,修改完成后再转换成字符串。

注:切片的底层指向一个数组,该数组的实际容量可能要大于切片所定义的容量。只有在没有任何切片指向的时候,底层的数组内存才会被释放,这种特性有时会导致程序占用多余的内存。

posted @   ArthurFleck  阅读(268)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示