GO 语言中 slice 理解

为什么说 Go 语言的 slice 是引用类型,其底层实现明明是一个结构体?

slice 的底层实现是一个包含三个字段的结构体:指向底层数组的指针、slice 的长度和 slice 的容量。当我们对 slice 进行操作时,例如添加或删除元素,实际上是在底层数组中进行操作。由于 slice 是一个指向底层数组的指针,因此多个 slice 可以共享同一个底层数组,这也是 slice 被称为引用类型的原因,也因此可以将其赋值为 nil(实际上是将底层结构体中的指向底层数组的指针设置为 nil)。

需要注意的是,虽然 slice 是引用类型,但是它并不是一个指针类型。因此,我们可以对 slice 进行赋值和传递,而不需要使用指针。这也是 Go 语言中 slice 的一个优点,它可以方便地进行传递和复制,而不需要担心底层数组的复制和传递带来的性能问题。

除了 slice,Go 语言中还有其他的引用类型,例如 map 和 channel

函数调用中修改 slice 的元素会影响原 slice 吗?

这里要分具体情况,如果在函数中对 slice 进行了 append 操作导致了 slice 扩容,那么扩容之后的 slice 的底层数据与原 slice 分离,就不会相互影响,否则会影响原 slice

//  初始化一个长度和容量不相同的 slice,函数中 append 操作没有导致底层数据扩容
// 所以对 slice[0] 的修改会影响原 slice
func Test_isSliceChangeIfAppend(t *testing.T) {
    slice := make([]int, 5, 10)
    fmt.Printf("origin slice:%v\n", slice)
    isSliceChangeIfAppend(slice)
    fmt.Printf("after append out func:%v\n", slice)
} func isSliceChangeIfAppend(origin []int) {
    origin = append(origin, 1, 2, 3)
    origin[0] = 1
    fmt.Printf("after append in func:%v\n", origin)
} -----output-----
origin slice:[0 0 0 0 0]
after append in func:[1 0 0 0 0 1 2 3]
after append out func:[1 0 0 0 0]
//  同上面的代码,初始化一个长度和容量相同的 slice
// 函数中的 append 操作就一定会扩容,后续修改也就不会影响原 slice
func Test_isSliceChangeIfAppend(t *testing.T) {
// 初始化一个长度和容量相同的 slice
slice := make([]int, 5)
fmt.Printf("origin slice:%v\n", slice)
isSliceChangeIfAppend(slice)
fmt.Printf("after append out func:%v\n", slice)
} func isSliceChangeIfAppend(origin []int) {
origin = append(origin, 1, 2, 3)
origin[0] = 1
fmt.Printf("after append in func:%v\n", origin)
} -----output-----
origin slice:[0 0 0 0 0]
after append in func:[1 0 0 0 0 1 2 3]
after append out func:[0 0 0 0 0]

![图片](https://mmbiz.qpic.cn/mmbiz_png/2fBauyxIV9YmLFQeheVRlib675c1S34fYGl7Y1RGmdwISIncPcibic1phDVRPaqUZKJUCx0lINWdqtWcJOpArFsKA/640?wx_fmt=png)

GO 语言中 slice 的理解的更多相关文章

  1. Go语言中slice使用注意事项

    Go 语言中的slice类型可以理解为是数组array类型的描述符,包含了三个因素: 指向底层数组的指针 slice目前使用到的底层数组的元素个数,即长度 底层数组的最大长度,即容量 因此当我们定义一 ...

  2. 对C语言中static的理解

    对C语言中的static关键字的深入理解 在一次面试的时候面试官问我static全局变量与全局变量的区别,之前虽然用过但是并没仔细去搞懂他,这次来细心的学习一下. 基本概念 使用static有三种情况 ...

  3. Go语言中slice作为参数传递时遇到的一些“坑”

    前言 相信看到这个题目,可能大家都觉得是一个老生常谈的月经topic了.一直以来其实把握一个"值传递"基本上就能理解各种情况了,不过最近遇到了更深一点的"小坑" ...

  4. c语言中pthread的理解和使用

    在头文件中看到#typedef unsigned long int pthread_t这句话怎么理解,pthread_t是一个什么类型呢? 相当于pthread_t实际是个unsigned long  ...

  5. Go语言中的slice

    Go语言中的slice有点类似于Java中的ArrayList,但在使用上更加灵活,先通过下面一个小例子来体验一下如何通过一个已有的切片来产生一个新切片: func main() { slice := ...

  6. [转]理解Go语言中的nil

    最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频. nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟 ...

  7. C语言中malloc函数的理解

    在C语言中malloc函数主要是用在堆内存的申请上,使用malloc函数时,函数会返回一个void *类型的值,这个值就是你申请的堆内存的首地址:为什么返回的地址是一个void *类型的地址呢?首先我 ...

  8. C语言中,头文件和源文件的关系(转)

    简单的说其实要理解C文件与头文件(即.h)有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句, ...

  9. C语言中的static 详细分析

    转自:http://blog.csdn.net/keyeagle/article/details/6708077/ google了近三页的关于C语言中static的内容,发现可用的信息很少,要么长篇大 ...

  10. C语言中void*详解及应用

    void在英文中作为名词的解释为“空虚:空间:空隙”:而在C语言中,void被翻译为“无类型”,相应的void *为“无类型指针”.void似乎只有“注释”和限制程序的作用,当然,这里的“注释”不是为 ...

随机推荐

  1. elk7.15.1安装部署搭建

    ELK简介 ELK是Elasticsearch.Logstash.Kibana三大开源框架首字母大写简称(但是后期出现的Filebeat(beats中的一种)可以用来替代Logstash的数据收集功能 ...

  2. win32api中文在线文档

    中文文档http://www.yfvb.com/help/win32sdk/ 英文手册https://www.jb51.net/books/724576.html

  3. Semantic Kernel 入门系列:🔥Kernel 内核和🧂Skills 技能

    理解了LLM的作用之后,如何才能构造出与LLM相结合的应用程序呢? 首先我们需要把LLM AI的能力和原生代码的能力区分开来,在Semantic Kernel(以下简称SK),LLM的能力称为 sem ...

  4. stable diffusion打造自己专属的LORA模型

    通过Lora小模型可以控制很多特定场景的内容生成. 但是那些模型是别人训练好的,你肯定很好奇,我也想训练一个自己的专属模型(也叫炼丹-_-). 甚至可以训练一个专属家庭版的模型(family mode ...

  5. golang 必会之 pprof 监控系列(5) —— cpu 占用率 统计原理

    golang pprof 监控系列(5) -- cpu 占用率 统计原理 大家好,我是蓝胖子. 经过前面的几节对pprof的介绍,对pprof统计的原理算是掌握了七八十了,我们对memory,bloc ...

  6. Yapi及Swgger使用+注解

    1.Yapi 1.1 介绍 YApi 是高效.易用.功能强大的 api 管理平台,旨在为开发.产品.测试人员提供更优雅的接口管理服务.可以帮助开发者轻松创建.发布.维护 API,YApi 还为用户提供 ...

  7. Appweb-6.1.1 移植到ARM

    Appweb-6.1.1 移植到ARM 编译环境:ubuntu-12.04 x64 开发平台:Hi3535 arm版 编译版本:appweb-6.1.1.zip ESP下载地址=> ESP we ...

  8. vue本地开发配置及项目部署

    一,  二,本地模拟配置代理,请求qq音乐的接口数据  三,axios请求头封装               参考http://www.axios-js.com/zh-cn/docs/#%E4%BB% ...

  9. 武装你的WEBAPI-OData Versioning

    本文属于OData系列 目录 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-OData资源更新Delt ...

  10. 2022-04-30:在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方。注意: 北方向 是y轴的正方向。 南方向 是y轴的负方向。 东方向 是x轴的正方向。 西方向 是x轴的负方向。 机器人

    2022-04-30:在无限的平面上,机器人最初位于 (0, 0) 处,面朝北方.注意: 北方向 是y轴的正方向. 南方向 是y轴的负方向. 东方向 是x轴的正方向. 西方向 是x轴的负方向. 机器人 ...