0

0

Go 语言多维切片创建与初始化深度解析

霞舞

霞舞

发布时间:2025-08-12 17:40:02

|

629人浏览过

|

来源于php中文网

原创

Go 语言多维切片创建与初始化深度解析

Go 语言中的多维切片,如 [][]uint8,本质上是“切片的切片”。其创建过程需要两阶段初始化:首先使用 make 分配外部切片,此时内部切片为零值(nil或空),然后通过循环为每个内部切片再次调用 make 分配具体存储空间。这种设计体现了 Go 切片的动态性和“锯齿状”特性,允许内部切片长度不一,而非传统意义上的连续多维数组。

Go 语言多维切片的构成

在 go 语言中,我们常说的“多维切片”实际上是“切片的切片”。例如,类型 [][]uint8 可以理解为 []([]uint8),即一个由 []uint8 类型切片组成的切片。这意味着外部切片的每个元素本身就是一个 uint8 类型的切片。这种结构与某些语言中内存连续的多维数组有所不同,go 的多维切片更类似于“锯齿状数组”(jagged array),即每个内部切片可以拥有独立的长度。

make 函数在切片创建中的作用

make 是 Go 语言内置的一个函数,用于创建切片(slice)、映射(map)和通道(channel)。对于切片而言,make(T, len, cap) 或 make(T, len) 会返回一个类型为 T 的切片,其长度为 len,容量为 cap(如果未指定,容量默认为 len)。make 函数会分配底层数组,并返回一个引用该数组的切片头。

多维切片的两阶段初始化过程

理解了多维切片的构成和 make 函数的作用后,我们就能明白为何创建多维切片通常需要两次 make 调用。

1. 第一阶段:创建外部切片

当你执行 pic := make([][]uint8, dy) 时,Go 语言会创建一个长度为 dy 的切片,这个切片的每个元素都是一个 []uint8 类型。然而,此时这些内部的 []uint8 切片并没有被分配实际的底层数组来存储 uint8 数据。它们被初始化为它们的零值,即 nil 切片(长度和容量都为0)。

我们可以通过以下示例代码来观察这一初始状态:

package main

import "fmt"

func main() {
    // 创建一个长度为2的 [][]uint8 外部切片
    ss := make([][]uint8, 2)
    fmt.Printf("ss:    %T %v 长度: %d\n", ss, ss, len(ss))

    // 遍历外部切片,查看每个内部切片的初始状态
    for i, s := range ss {
        fmt.Printf("ss[%d]: %T %v 长度: %d\n", i, s, s, len(s))
    }
}

运行上述代码,输出将是:

ss:    [][]uint8 [[] []] 长度: 2
ss[0]: []uint8 [] 长度: 0
ss[1]: []uint8 [] 长度: 0

从输出中可以看出,ss 是 [][]uint8 类型,它包含了两个元素,但每个元素(即 ss[0] 和 ss[1])都是一个空的 []uint8 切片,它们的长度均为 0。

Lateral App
Lateral App

整理归类论文

下载

2. 第二阶段:初始化内部切片

为了让每个内部切片能够存储 uint8 类型的数据,你需要为它们单独分配底层数组。这通常通过一个循环来完成:

for i := range pic {
    pic[i] = make([]uint8, dx) // 为每个内部切片分配长度为 dx 的空间
    // ... 此时 pic[i] 已经是一个可用的 []uint8 切片,可以存储 dx 个 uint8 元素
}

在这个循环中,pic[i] = make([]uint8, dx) 会为 pic 切片中的每一个元素(即每一个 []uint8 切片)分配一个长度为 dx 的底层数组。这样,pic[i] 才真正成为一个可以容纳 dx 个 uint8 数据的切片。

完整示例:生成图像像素数据

结合上述两阶段初始化,我们可以理解 Go Tour 中生成图像像素数据的 Pic 函数:

func Pic(dx, dy int) [][]uint8 {
    // 第一阶段:创建外部切片,长度为 dy。
    // 此时 pic 是一个包含 dy 个 nil []uint8 切片的切片。
    pic := make([][]uint8, dy)

    // 第二阶段:遍历外部切片,为每个内部切片分配空间。
    // 确保每个 pic[i] 都是一个长度为 dx 的 []uint8 切片。
    for i := range pic {
        pic[i] = make([]uint8, dx)
        // 此时 pic[i] 已经可以安全地访问其元素
        for j := range pic[i] {
            // 填充像素数据,例如 (i+j)/2
            pic[i][j] = uint8((i + j) / 2)
        }
    }
    return pic
}

这段代码清晰地展示了如何通过两次 make 调用来构建一个 dy 行 dx 列的二维 uint8 切片。

注意事项与总结

  • 非连续内存: Go 语言的多维切片并非像 C/C++ 数组那样在内存中连续存储所有元素。外部切片存储的是指向内部切片底层数组的指针(或切片头结构)。
  • 灵活性: 这种两阶段初始化和“锯齿状”特性赋予了 Go 多维切片极大的灵活性。你可以创建内部切片长度不一的结构,例如 [][]uint8,其中 pic[0] 的长度是 10,而 pic[1] 的长度是 20。
  • 并非冗余: 两次 make 调用并非冗余,而是 Go 语言设计多维切片所必需的步骤。第一次 make 分配了外部切片的结构,第二次 make 则为每个内部切片分配了实际的数据存储空间。
  • 固定大小: 如果你需要一个严格固定大小且内存连续的二维结构,可以考虑使用数组的数组,例如 [N][M]uint8。但切片通常更常用,因为它提供了动态大小的便利性。

总之,Go 语言的多维切片是“切片的切片”,其创建过程需要明确地为外部切片和每一个内部切片分配内存。理解这一机制对于有效地使用 Go 语言处理复杂数据结构至关重要。

相关专题

更多
treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

5

2025.12.22

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

45

2025.09.03

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

45

2025.09.03

golang map内存释放
golang map内存释放

本专题整合了golang map内存相关教程,阅读专题下面的文章了解更多相关内容。

73

2025.09.05

golang map相关教程
golang map相关教程

本专题整合了golang map相关教程,阅读专题下面的文章了解更多详细内容。

25

2025.11.16

golang map原理
golang map原理

本专题整合了golang map相关内容,阅读专题下面的文章了解更多详细内容。

36

2025.11.17

java判断map相关教程
java判断map相关教程

本专题整合了java判断map相关教程,阅读专题下面的文章了解更多详细内容。

31

2025.11.27

桌面文件位置介绍
桌面文件位置介绍

本专题整合了桌面文件相关教程,阅读专题下面的文章了解更多内容。

0

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号