Go数组、多维数组和切片(动态数组),及常用函数len(),cap(),copy(),append()在切片中的使用

简介: 本文介绍了Go语言中数组、多维数组和切片(动态数组)的基本概念和操作,包括数组的定义、初始化、访问,多维数组的定义和访问,以及切片的创建、使用和扩容。同时,还讲解了切片中常用的函数len()、cap()、copy()和append()的使用方法。

Go数组、多维数组和切片(动态数组)

1.数组(一维数组)

数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,数组元素通过索引(下标)来读取,修改数组元素值。

数组定义格式:

var 数组名 [size--数组长度] 数据类型

数组初始化

  1. 先声明,再进行初始化

    // var 数组名 [size] 数据类型 
    var arr3 [3]int
    // 根据索引下标进行赋值
    arr3[0] = 1024
    arr3[1] = 512
    arr3[2] = 256
    
  2. 数组长度确定,在声明定义时进行初始化

    var arr = [size] arr_type {
         ele1,ele2...,elen} 
    // 使用 :=
    arr := [size] arr_type {
         ele1,ele2...,elen}
    

    例如,声明并且初始化 arr1 和 arr2 两个数组

    var arr1 = [10]int{
         1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    // 或者下面的格式,使用:=来进行快速初始化
    arr2 := [10]int{
         1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    // 使用 range 进行 for遍历
    for _, v := range arr1 {
         
        fmt.Print(v, "\t") 
        // 1       2       3       4       5       6       7       8       9       10
    }re
    println()
    for _, v := range arr2 {
         
        fmt.Print(v,"\t")
        // 1       2       3       4       5       6       7       8       9       10
    }
    
  3. 数组长度不确定,在声明定义时初始化

    Go为我们提供了...的方式来对长度不确定的数组,进行初始化,其编译器会自行推断数组的长度。

    格式如下

    var arr = [...] 数据类型 {
         元素1,元素2,...,元素n}
    

    例如:

    var arr4 = [...]string{
         
        "张三",
        "李四",
        "王五",
    }
    println(len(arr4)) // ... 为 3
    // 注意,数组中的每个元素需要以逗号分隔,
    // 字符串数组中最后一个元素后也需要加分号
    

数组元素访问:

通过索引下标来访问数组元素:

var arrTest = [4] int {
   1,7,8,3}
element1 = arrTest[0] // 1
element1 = arrTest[3] // 3

2.多维数组

  1. 多维数组定义格式:

    var arrD [size][size] arr_type
    

    注意数组的数据类型必须是统一的且唯一的。

  2. 多维数组的初始化:

    多维数组的声明及初始化与一维数组是完全一样的,以二维数组举例

    var arrD = [size][size] arr_type{
         ele1,ele2...,elen}
    // 或者
    arrD := [size][size] arr_type{
         ele1,ele2...,elen}
    

    在二维数组中不能使用...来进行数组长度不确定。

  3. 多维数组的元素访问:

    与一维数组是完全一样的

    var arrDT = [3][3] int {
         {
         1,3,9},{
         2,4,6},{
         5,7,8}}
    ele1 := arrDT [2] [0] // 5
    ele2 := arrDT [1] [2] // 6
    ele3 := arrDT [0] [1] // 3
    

3.切片(动态数组)

Go 语言切片是对数组的抽象。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

  1. 切片的定义格式

    切片不需要声明长度,所以可以使用未定义数组长度来声明一个切片

    var 切片名 []type
    

    经常使用make()函数来定义声明一个切片,如下:

    // make 函数的格式
    var slice1 []type = make([]type, len)
    // 也可以简写为
    slice1 := make([]type, len)
    

    make 函数的格式:

    make([]type, len ,[capacity]) 
    // type 为切片的数据类型
    // len 为切片的初始化长度
    // capacity 为切片的最大容量,capacity为可选参数
    

    若capacity 不写,则默认与len保持一致。

  2. 切片的使用

    go语言提供的切片与python中的切片使用方式基本一致(切片为左闭右开,即包含左边不包含右边)

    切片格式如下:

    var arr = [size] arr_type {
         ele1,ele2,ele3...elen}
    // 对上面的数组进行切片 起始索引 结束索引,切片为左闭右开的格式
    var slice = arr [startIndex : endIndex] 
    // startIndex 为空,则从开始切到endIndex
    // endIndex 为空,则从startIndex 切到 末尾
    // startIndex endIndex 都为空则从开头切到末尾
    

    使用例子如下(tip:可以使用%v进行对切片的值显示):

    // 先创建一个数组,方便一会儿切片来进行测试
    var arr1 = [6]string{
         "java", "python", "go", "rust", "c++", "php"}
    // 1. 从开头切到尾部,相当于一层拷贝,而且可以进行动态扩容
    slice1 := arr1[:]
    println("slice1", slice1) // slice1 [6/6]0xc000057f10
    // 2. 指定起始位置,默认位置不指示
    slice2 := arr1[1:4]
    println("slice2", slice2) // slice1 [3/5]0xc000057f20
    // 3. 指定终止位置,起始位置不指定
    slice3 := arr1[:3]
    println("slice3", slice3) //slice3 [3/6]0xc000057f10
    // 4. 指定区间
    slice4 := arr1[1:3]
    println("slice4", slice4) // slice4 [2/5]0xc000057f20
    // 切片遍历显示,这里只拿slice4来进行演示
    for item := range slice4 {
         
        println(slice4[item]) // python go 可见切片是左开右闭的
    }
    
  3. len() 和 cap() 及 append ()和 copy()函数

    切片是可索引的,并且可以由 len() 方法获取长度。

    切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。

    append() 函数可以对切片进行末尾追加,即动态扩容

    copy() 函数 拷贝切片。

    切片的扩容,每次是以两倍的方式进行的。

    // 创建数组
    var arr2 = [3]int{
         123, 456, 789}
    // 进行切片
    sliceN := arr2[:]
    println(len(sliceN))
    println(cap(sliceN))
    // 验证其是否为动态数组,使用append追加
    sliceN = append(sliceN, 333)
    println(len(sliceN)) // 4
    println(cap(sliceN)) // 6
    // 使用make函数创建切片
    sliceN2 := make([]int, 3, 6)
    println(len(sliceN2)) // 3
    println(cap(sliceN2)) // 6
    // copy 拷贝切片
    sliceN3 := make([]int, 3, 12)
    copy(sliceN3, sliceN)
    fmt.Printf("%v,%d,%d", sliceN3, len(sliceN3), cap(sliceN3))
    // [123 456 789],3,12
    

相关文章
|
1月前
|
Go
【LeetCode 热题100】DP 实战进阶:最长递增子序列、乘积最大子数组、分割等和子集(力扣300 / 152/ 416 )(Go语言版)
本文深入解析三道经典的动态规划问题:**最长递增子序列(LIS)**、**乘积最大子数组** 和 **分割等和子集**。 - **300. LIS** 通过 `dp[i]` 表示以第 `i` 个元素结尾的最长递增子序列长度,支持 O(n²) 动态规划与 O(n log n) 的二分优化。 - **152. 乘积最大子数组** 利用正负数特性,同时维护最大值与最小值的状态转移方程。 - **416. 分割等和子集** 转化为 0-1 背包问题,通过布尔型 DP 实现子集和判断。 总结对比了三题的状态定义与解法技巧,并延伸至相关变种问题,助你掌握动态规划的核心思想与灵活应用!
75 1
|
2月前
|
安全 Go 开发者
Go语言之切片的原理与用法 - 《Go语言实战指南》
切片(slice)是Go语言中用于处理变长数据集合的核心结构,基于数组的轻量级抽象,具有灵活高效的特点。切片本质是一个三元组:指向底层数组的指针、长度(len)和容量(cap)。本文详细介绍了切片的声明与初始化方式、基本操作(如访问、修改、遍历)、长度与容量的区别、自动扩容机制、共享与副本处理、引用类型特性以及常见陷阱。通过理解切片的底层原理,开发者可以更高效地使用这一数据结构,优化代码性能。
|
2月前
|
Go 索引
Go语言数组的定义与操作 - 《Go语言实战指南》
本文介绍了 Go 语言中的数组(Array)相关知识,包括定义、初始化方式(默认、显式、指定索引及自动推导长度)、访问与修改、遍历方法(for 循环和 for range)、值类型特性(复制行为)、多维数组支持以及其与切片的区别。数组是定长且同类型的集合,适合性能敏感场景,但实际开发中更常用动态的切片(slice)。
|
5月前
|
测试技术 Go API
Go 切片导致 rand.Shuffle 产生重复数据的原因与解决方案
在 Go 语言开发中,使用切片时由于其底层数据共享特性,可能会引发意想不到的 Bug。本文分析了 `rand.Shuffle` 后切片数据重复的问题,指出原因在于切片是引用类型,直接赋值会导致底层数组共享,进而影响原始数据。解决方案是使用 `append` 进行数据拷贝,确保独立副本,避免 `rand.Shuffle` 影响原始数据。总结强调了切片作为引用类型的特性及正确处理方法,确保代码稳定性和正确性。
166 82
|
7月前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
125 7
|
2月前
|
人工智能 Go
[go]Slice 切片原理
本文详细介绍了Go语言中的切片(slice)数据结构,包括其定义、创建方式、扩容机制及常见操作。切片是一种动态数组,依托底层数组实现,具有灵活的扩容和传递特性。文章解析了切片的内部结构(包含指向底层数组的指针、长度和容量),并探讨了通过`make`创建切片、基于数组生成切片以及切片扩容的规则。此外,还分析了`append`函数的工作原理及其可能引发的扩容问题,以及切片拷贝时需要注意的细节。最后,通过典型面试题深入讲解了切片在函数间传递时的行为特点,帮助读者更好地理解和使用Go语言中的切片。
|
5月前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
132 3
Go 语言入门指南:切片
|
7月前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
166 67
|
5月前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
5月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。