小工具知识网

当前位置: 首页 > 行业知识 > 【Go语言入门教程】Go语言容器(container)

行业知识

【Go语言入门教程】Go语言容器(container)

2026-11-02 05:11:48 来源:互联网转载

Go语言数组的声明

数组的声明语法如下:

var 数组变量名 [元素数量]Type

语法说明如下所示:

  • 数组变量名:数组声明及使用时的变量名。
  • 元素数量:数组的元素数量,可以是一个表达式,但最终通过编译期计算的结果必须是整型数值,元素数量不能含有到运行时才能确认大小的数值。
  • Type:可以是任意基本类型,包括数组本身,类型为数组本身时,可以实现多维数组。

    数组的每个元素都可以通过索引下标来访问,索引下标的范围是从 0 开始到数组长度减 1 的位置,内置函数 len() 可以返回数组中元素的个数。

    var a [3]int // 定义三个整数的数组

    fmt.Println(a[0]) // 打印第一个元素

    fmt.Println(a[len(a)-1]) // 打印最后一个元素

    // 打印索引和元素

    for i, v := range a {

    fmt.Printf(“%d %d\n”, i, v)

    }

    // 仅打印元素

    for _, v := range a {

    fmt.Printf(“%d\n”, v)

    }

    默认情况下,数组的每个元素都会被初始化为元素类型对应的零值,对于数字类型来说就是 0,同时也可以使用数组字面值语法,用一组值来初始化数组:

    var q [3]int = [3]int{1, 2, 3}

    var r [3]int = [3]int{1, 2}

    fmt.Println(r[2]) // “0”

    在数组的定义中,如果在数组长度的位置出现“…”省略号,则表示数组的长度是根据初始化值的个数来计算,因此,上面数组 q 的定义可以简化为:

    q := […]int{1, 2, 3}

    fmt.Printf(“%T\n”, q) // “[3]int”

    数组的长度是数组类型的一个组成部分,因此 [3]int 和 [4]int 是两种不同的数组类型,数组的长度必须是常量表达式,因为数组的长度需要在编译阶段确定。

    q := [3]int{1, 2, 3}

    q = [4]int{1, 2, 3, 4} // 编译错误:无法将 [4]int 赋给 [3]int

    比较两个数组是否相等

    如果两个数组类型相同(包括数组的长度,数组中元素的类型)的情况下,我们可以直接通过较运算符(==和!=)来判断两个数组是否相等,只有当两个数组的所有元素都是相等的时候数组才是相等的,不能比较两个类型不同的数组,否则程序将无法完成编译。

    a := [2]int{1, 2}

    b := […]int{1, 2}

    c := [2]int{1, 3}

    fmt.Println(a == b, a == c, b == c) // “true false false”

    d := [3]int{1, 2}

    fmt.Println(a == d) // 编译错误:无法比较 [2]int == [3]int

    遍历数组——访问每一个数组元素

    遍历数组也和遍历切片类似,代码如下所示:

    var team [3]string

    team[0] = “hammer”

    team[1] = “soldier”

    team[2] = “mum”

    for k, v := range team {

    fmt.Println(k, v)

    }

    代码输出结果:

    0 hammer

    1 soldier

    2 mum

    代码说明如下:

    • 第 6 行,使用 for 循环,遍历 team 数组,遍历出的键 k 为数组的索引,值 v 为数组的每个元素值。
    • 第 7 行,将每个键值打印出来。

      Go语言多维数组简述

      Go语言中允许使用多维数组,因为数组属于值类型,所以多维数组的所有维度都会在创建时自动初始化零值,多维数组尤其适合管理具有父子关系或者与坐标系相关联的数据。

      声明多维数组的语法如下所示:

      var array_name [size1][size2]…[sizen] array_type

      其中,array_name 为数组的名字,array_type 为数组的类型,size1、size2 等等为数组每一维度的长度。

      结合上一节《Go语言数组》中所学到的知识,下面以二维数组为例来简单讲解一下多维数组的使用。

      二维数组是最简单的多维数组,二维数组本质上是由多个一维数组组成的。

      【示例 1】声明二维数组

      // 声明一个二维整型数组,两个维度的长度分别是 4 和 2

      var array [4][2]int

      // 使用数组字面量来声明并初始化一个二维整型数组

      array = [4][2]int{{10, 11}, {20, 21}, {30, 31}, {40, 41}}

      // 声明并初始化数组中索引为 1 和 3 的元素

      array = [4][2]int{1: {20, 21}, 3: {40, 41}}

      // 声明并初始化数组中指定的元素

      array = [4][2]int{1: {0: 20}, 3: {1: 41}}

      下图展示了上面示例中声明的二维数组在每次声明并初始化后包含的值。

      图:二维数组及其外层数组和内层数组的值

      为了访问单个元素,需要反复组合使用[ ]方括号,如下所示。

      【示例 2】为二维数组的每个元素赋值

      // 声明一个 2×2 的二维整型数组

      var array [2][2]int

      // 设置每个元素的整型值

      array[0][0] = 10

      array[0][1] = 20

      array[1][0] = 30

      array[1][1] = 40

      只要类型一致,就可以将多维数组互相赋值,如下所示,多维数组的类型包括每一维度的长度以及存储在元素中数据的类型。

      【示例 3】同样类型的多维数组赋值

      // 声明两个二维整型数组

      var array1 [2][2]int

      var array2 [2][2]int

      // 为array2的每个元素赋值

      array2[0][0] = 10

      array2[0][1] = 20

      array2[1][0] = 30

      array2[1][1] = 40

      // 将 array2 的值复制给 array1

      array1 = array2

      因为数组中每个元素都是一个值,所以可以独立复制某个维度,如下所示。

      【示例 4】使用索引为多维数组赋值

      // 将 array1 的索引为 1 的维度复制到一个同类型的新数组里

      var array3 [2]int = array1[1]

      // 将数组中指定的整型值复制到新的整型变量里

      var value int = array1[1][0]

      Go语言切片详解

      切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型(因此更类似于 C/C++ 中的数组类型,或者 Python 中的 list 类型),这个片段可以是整个数组,也可以是由起始和终止索引标识的一些项的子集,需要注意的是,终止索引标识的项不包括在切片内。

      Go语言中切片的内部结构包含地址、大小和容量,切片一般用于快速地操作一块数据集合,如果将数据集合比作切糕的话,切片就是你要的“那一块”,切的过程包含从哪里开始(切片的起始位置)及切多大(切片的大小),容量可以理解为装切片的口袋大小,如下图所示。

      图:切片结构和内存分配

      从数组或切片生成新的切片

      切片默认指向一段连续内存区域,可以是数组,也可以是切片本身。

      从连续内存区域生成切片是常见的操作,格式如下:

      slice [开始位置 : 结束位置]

      语法说明如下:

      • slice:表示目标切片对象;
      • 开始位置:对应目标切片对象的索引;
      • 结束位置:对应目标切片的结束索引。

        从数组生成切片,代码如下:

        var a = [3]int{1, 2, 3}

        fmt.Println(a, a[1:2])

        其中 a 是一个拥有 3 个整型元素的数组,被初始化为数值 1 到 3,使用 a[1:2] 可以生成一个新的切片,代码运行结果如下:

        [1 2 3] [2]

        其中 [2] 就是 a[1:2] 切片操作的结果。

        从数组或切片生成新的切片拥有如下特性:

        • 取出的元素数量为:结束位置 - 开始位置;
        • 取出元素不包含结束位置对应的索引,切片最后一个元素使用 slice[len(slice)] 获取;
        • 当缺省开始位置时,表示从连续区域开头到结束位置;
        • 当缺省结束位置时,表示从开始位置到整个连续区域末尾;
        • 两者同时缺省时,与切片本身等效;
        • 两者同时为 0 时,等效于空切片,一般用于切片复位。

          根据索引位置取切片 slice 元素值时,取值范围是(0~len(slice)-1),超界会报运行时错误,生成切片时,结束位置可以填写 len(slice) 但不会报错。

          下面通过实例来熟悉切片的特性。

          1) 从指定范围中生成切片

          切片和数组密不可分,如果将数组理解为一栋办公楼,那么切片就是把不同的连续楼层出租给使用者,出租的过程需要选择开始楼层和结束楼层,这个过程就会生成切片,示例代码如下:

          var highRiseBuilding [30]int

          for i := 0; i

          highRiseBuilding[i] = i + 1

          }

          // 区间

          fmt.Println(highRiseBuilding[10:15])

          // 中间到尾部的所有元素

          fmt.Println(highRiseBuilding[20:])

          // 开头到中间指定位置的所有元素

          fmt.Println(highRiseBuilding[:2])

          代码输出如下:

          [11 12 13 14 15]

          [21 22 23 24 25 26 27 28 29 30]

          [1 2]

          代码中构建了一个 30 层的高层建筑,数组的元素值从 1 到 30,分别代表不同的独立楼层,输出的结果是不同的租售方案。

          代码说明如下:

          • 第 8 行,尝试出租一个区间楼层。
          • 第 11 行,出租 20 层以上。
          • 第 14 行,出租 2 层以下,一般是商用铺面。

            切片有点像C语言里的指针,指针可以做运算,但代价是内存操作越界,切片在指针的基础上增加了大小,约束了切片对应的内存区域,切片使用中无法对切片内部的地址和大小进行手动调整,因此切片比指针更安全、强大。

            2) 表示原有的切片

            生成切片的格式中,当开始和结束位置都被忽略时,生成的切片将表示和原切片一致的切片,并且生成的切片与原切片在数据内容上也是一致的,代码如下:

            a := []int{1, 2, 3}

            fmt.Println(a[:])

            a 是一个拥有 3 个元素的切片,将 a 切片使用 a[:] 进行操作后,得到的切片与 a 切片一致,代码输出如下:

            [1 2 3]

            3) 重置切片,清空拥有的元素

            把切片的开始和结束位置都设为 0 时,生成的切片将变空,代码如下:

            a := []int{1, 2, 3}

            fmt.Println(a[0:0])

            代码输出如下:

            []

            直接声明新的切片

            除了可以从原有的数组或者切片中生成切片外,也可以声明一个新的切片,每一种类型都可以拥有其切片类型,表示多个相同类型元素的连续集合,因此切片类型也可以被声明,切片类型声明格式如下:

            var name []Type

            其中 name 表示切片的变量名,Type 表示切片对应的元素类型。

            自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

            深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

            因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

            既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

            由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

            如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)

            一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

            998668266)]

            [外链图片转存中…(img-tReieKsn-1712998668267)]

            既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

            由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

            如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)

            [外链图片转存中…(img-dLQ9EdlS-1712998668267)]

            一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

上一篇:网店源码揭秘,构建优质电商平台的关键要素与策略解析

下一篇:探索Python背后的秘密,揭示Python的魅力与优势!