首页 > 其他分享 >Go 语言中的 切片 --slice

Go 语言中的 切片 --slice

时间:2024-10-24 15:13:05浏览次数:7  
标签:std slice -- C++ 切片 vector 数组 Go

为了更好地理解 Go 语言中的 切片(slice),我们可以将它与 C++ 中的数组或容器(如 std::vector)进行比较,但要注意的是,它们之间有一些关键的区别。让我们逐步将 Go 的切片与 C++ 中的概念进行对应:

1. 数组 vs 切片

在 C++ 中,数组(array) 是一种固定大小的数据结构,大小必须在编译时确定,并且不能动态调整。例如:

int arr[5] = {1, 2, 3, 4, 5};  // C++ 中的静态数组,大小为5

Go 语言中的 数组 也是固定大小的,一旦定义,其长度是不可变的。例如:

var arr [5]int = [5]int{1, 2, 3, 4, 5}  // Go中的数组,大小为5

但是 Go 中的 切片(slice) 是一种动态、可变长度的结构,相当于在 C++ 中使用 std::vector。Go 的切片是对底层数组的引用,可以在运行时动态调整大小。

2. 切片 vs std::vector

C++ 中的 std::vector 与 Go 语言中的 切片(slice) 比较类似。两者都提供了可变长度的数组功能,并且它们都可以动态增加或缩小。

  • C++ 中的 std::vector
#include <vector>
std::vector<int> vec = {1, 2, 3, 4, 5};  // C++ 中的动态数组
vec.push_back(6);  // 动态增加元素
  • Go 中的 切片
slice := []int{1, 2, 3, 4, 5}  // Go 中的切片
slice = append(slice, 6)  // 动态增加元素

在 C++ 中,std::vector 可以动态调整大小,并自动管理底层内存。同样地,Go 的切片也可以通过 append 函数动态增加元素。就像 std::vector 可以在其容量不足时自动分配更多内存,Go 的切片也是如此。

3. 长度和容量

  • 在 C++ 的 std::vector 中,容量(capacity)指的是分配的内存空间大小,可以容纳的元素数量,而长度(size)指的是实际存储的元素个数。

    std::vector<int> vec = {1, 2, 3};
    int size = vec.size();      // 当前存储的元素个数,输出: 3
    int capacity = vec.capacity();  // 分配的内存容量
    
  • 在 Go 中,切片也有类似的概念:

    • 长度(len):切片中实际包含的元素个数。
    • 容量(cap):从切片的起始位置到底层数组末尾的元素数量。
    slice := []int{1, 2, 3}
    fmt.Println(len(slice))  // 输出:3
    fmt.Println(cap(slice))  // 输出:3
    

当向 std::vector 或切片追加元素时,容量不足时会重新分配更大的内存空间。

4. 底层数组和内存共享

在 C++ 中,当你操作 std::vector 时,通常是一个独立的内存块,每次操作都不会影响到其他 vector。然而,在 Go 中,切片是共享底层数组的。如果从一个数组或切片中创建另一个切片,多个切片可以共享同一底层数组。这与 C++ 的数组指针类似。

例如,假设我们有一个 C++ 的数组指针:

int arr[] = {1, 2, 3, 4, 5};
int* ptr = arr + 1;  // 指向数组的第二个元素
ptr[0] = 100;        // 修改数组

这种情况下,修改 ptr 所指向的内容会影响到原始数组。

在 Go 中,切片共享底层数组的特性与此类似:

arr := [5]int{1, 2, 3, 4, 5}
slice1 := arr[1:4]  // 创建一个从索引1到3的切片
slice1[0] = 100     // 修改 slice1 的第一个元素,影响了底层数组
fmt.Println(arr)    // 输出: [1 100 3 4 5]

5. append 函数的行为

当我们在 Go 中向切片追加元素时,底层数组的容量可能会重新分配。当容量不足时,Go 会创建一个新的底层数组,并将现有的数据复制过去,这与 C++ 中 std::vector 的扩容机制类似。

  • 在 C++ 中,当 std::vector 容量不足时,会自动分配更多内存,现有元素会被复制到新的内存空间中。
  • 在 Go 中,append 可能会导致重新分配底层数组,类似地也会将现有数据复制到新的数组中。
std::vector<int> vec = {1, 2, 3};
vec.push_back(4);  // 如果容量不足,重新分配内存

Go 中的对应逻辑:

slice := []int{1, 2, 3}
slice = append(slice, 4)  // 如果容量不足,重新分配底层数组

6. C++ 中的指针 vs Go 中的切片

在 C++ 中,如果你通过指针操作数组的部分元素,或者传递数组指针到函数内,这种行为类似于 Go 中的切片。例如:

  • C++ 中通过指针操作数组:
void modifyArray(int* arr) {
    arr[0] = 100;
}

int main() {
    int arr[] = {1, 2, 3};
    modifyArray(arr);
    // arr[0] 现在是 100
}
  • 在 Go 中,切片类似于数组的引用,因此可以在函数中直接修改底层数组:
func modifySlice(s []int) {
    s[0] = 100
}

func main() {
    arr := []int{1, 2, 3}
    modifySlice(arr)
    fmt.Println(arr)  // 输出: [100 2 3]
}

7. 总结:C++ vs Go 切片理解

  • 切片与 C++ 的 std::vector 相似,因为两者都可以动态扩展,并且容量和长度是分开的概念。
  • 切片共享底层数组,类似于在 C++ 中通过指针访问数组的某部分,多个切片可以引用同一块内存。
  • Go 切片的追加操作append)与 C++ 中 std::vector 的扩容机制类似,当容量不足时,会自动分配新的更大的底层数组。
  • 切片的指针行为 类似于 C++ 中通过指针操作数组元素的方式。

理解这些相似点和不同点,可以帮助你更快适应 Go 的切片操作,特别是在你熟悉 C++ 的数组和 std::vector 时。

标签:std,slice,--,C++,切片,vector,数组,Go
From: https://www.cnblogs.com/niumachen/p/18499630

相关文章

  • UML类图
    UML单个类图的基本属性属性的表现形式是[可见性]属性名:类型[=默认值]操作的表现形式是[可见性]名称(参数列表)[:返回类型]一般类的类名用正常字体粗体表示,如上图;抽象类名用斜体字粗体,如User;接口则需在上方加上<<interface>>。属性和方法都需要标注可见性符号,+代表public,#......
  • 基于python的金融分析与风险管理-代码块-c8-股票投资组合
    绘图importnumpyasnpimportpandasaspdimportmatplotlib.pyplotasplt##Matplotlib是一个用于绘制数据可视化的Python库。它提供了一种类似于Matlab的绘图接口,可以用于生成各种静态、动态、交互式的图形,包括线图、散点图、柱状图、饼图、等高线图等。###Matplotlib......
  • chrome 控制台console 调用vue页面的方法--来自chatgpt的回答
    问题二:vue2的项目中chrome控制台输入$0.vue会输出什么在Vue2项目中,如果你在Chrome控制台中输入$0.__vue__,这个命令会返回$0当前选中的DOM元素对应的Vue实例。解释:$0:代表ChromeDevTools中当前选中的DOM元素。.vue:这是Vue2中的一个内部属性,它持有与该D......
  • vue - 选项卡右击下拉框
    在element-ui环境下,给选项卡添加右击事件,是相当麻烦的一件事情,主要是麻烦,很多东西都需要注意,并没有太多难点。注意项el-tabs的右击事件事件的名称是contextmenu.prevent.native,这个很快就能找到,需要注意的是:选项卡整个头部都能触发右击事件,需要过滤出哪些事件是由选项卡......
  • 实验2 类和对象_基础编程1
    实验任务1:t.h源码:1#pragmaonce23#include<string>45//类T:声明6classT{7//对象属性、方法8public:9T(intx=0,inty=0);//普通构造函数10T(constT&t);//复制构造函数11T(T&&t);//移动构造函数12......
  • 网格元素-grid-area
    发现一个好用的界面布局css属性<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>菜鸟教程(runoob.com)</title><style>.item1{grid-area:header;}.item2{grid-area:menu;}.item3{grid-area:main;}.item......
  • vue - 自定义吸附窗口
    业务需求以共享单车界面为例,地图上分布着大量的共享单车,鼠标悬浮在单车上,弹出一个吸附弹窗,内容显示单车详细信息。分析很明显,因为单车的数量可能非常多,我们不可能用显示隐藏的方式实现;合理的做法是,所有单车公用一个弹窗面板,悬浮的时候刷新面板上的数据。方案看着改吧,element......
  • 20222305 2024-2025-1 《网络与系统攻防技术》实验三实验报告
    网络攻防实验报告姓名:田青学号:20222305实验日期:2024/10/18—2024/10/31实验名称:后门原理与实践指导教师:王志强1.实验内容本周学习内容总结:1.用户态(ring3)和内核态(ring0),切换时机:系统调用、中断、异常。2.自启动技术。3.进程隐藏技术实现:1>改名2>基于系统服务的伪装3>......
  • 如何快速在github中下载东西
    快速在github中下载东西的方法:1.使用GitClone;2.使用GitHubDesktop;3.使用下载按钮;4.使用wget或curl;5.使用GitHubCLI。Git是GitHub的基础技术,你可以使用GitClone命令从GitHub上克隆(下载)整个仓库到你的本地计算机。1.使用GitCloneGit是GitHub的基础技术,你可以使用Git......
  • GO:可变长参数和切片作为函数参数
    在Go语言中,可变函数参数(可变长参数)和切片作为函数参数是两个不同的概念,虽然它们都能处理多个元素,但它们的用途和处理方式有所不同。以下是它们之间的详细区别:1.可变函数参数(VariadicFunctionParameters)可变参数函数可以接受不定数量的参数,使用...运算符来定义。这些参数......