说明

因为slice是指针类型,所以很多人会误以为其传递的是引用,所以在使用的过程中会出现一些非期望的实现。

问题

在使用append函数时,比如以下函数:

func sliceModify(slice []int) {// slice[0] = 88slice = append(slice, 6)
}
func main() {slice := []int{1, 2, 3, 4, 5}sliceModify(slice)fmt.Println(slice)
}
// [1 2 3 4 5]

为什么append的数组在外部没有改变呢,因为slice传的是值,虽然改变了底层数据,但是外部slice的状态并没改变。也许有人质疑值语义,但是有以下代码

func modifySlice(data []int) {data = nil
}
func main() {a := []int{1,2,3}fmt.Println(a)modifySlice(a)fmt.Println(a)
}
// [1, 2, 3]
// [1, 2, 3]

从上面代码可以看到,改变slice本身的值并不会改变外部的值,及是值语义。

那么如何解决值传递带来的问题,解决方法一,就是将slice作为指针传递:

func sliceModify(slice *[]int) {*slice = append(*slice, 6)
}
func main() {slice := []int{1, 2, 3, 4, 5}sliceModify(&slice)fmt.Println(slice)
}

指针会改变原本变量的状态,所以外部的slice发生了改变。

另一种解决方法是改变外部变量的状态,如下代码:

func main() {    s1 := make([] int ,3,5)    s1[0] = 1 s1[1] = 2    fmt.Println(s1)     s2 :=s1[:4]
}
func test( s [] int )  {    s = append(s,3)   fmt.Println(s)
}
//[1 2 0 3]
//[1 2 0]
//[1 2 0 3]

虽然在函数内修改slice但是只是添加到了内存中,所以在函数中内printf出来,但是外部的len没有改变,所以不会显示,如果强制改变其状态,那么添加的值也就显露出来了。

[Golang]slice值传递存在的问题相关推荐

  1. Golang中的值传递和引用传递

    一.前言 我在刚开始学习golang的时候,被值传递和引用传递困扰了一段时间,因为我之前是学习Java的,深受Java面向对象思想的影响,转成golang的时候就会想不通结构体等类型(看起来像是Jav ...

  2. go slice获取唯一值_Go语言引用传递与值传递

    先说结论 GO中只有值传递,没有引用传递 所谓值传递,就是实参通过拷贝将自身内容传递给形参.也就是将传递的内容拷贝一份,给函数.所以函数外和函数里对这个参数地址求值,应该是不一样的. 证明如下: fu ...

  3. PHP 怎样理解go指针,golang指针传递和值传递的区别是什么?

    Go允许通过指针(有时称为引用)和值来传递参数.在这篇文章中,我们将比较两种方法,特别注意可能影响选择的不同情境. 指针传递与值传递 严格地说,go方法或函数只有一种传递方式,那就是值传递.每次将一个 ...

  4. golang的基本数据类型和数组默认都是值传递的

    基本数据类型和数组默认都是值传递的,即进行值拷贝.在函数内修改,不会影响到原来的值. 以值传递方式的数据类型,如果希望在函数内的变量能修改函数外的变量,可以传入变量的地址&,函数内以指针的方式 ...

  5. Go语言之值传递与引用传递

    参考[1] Go语言中函数的参数有两种传递方式:按值传递和按引用传递. Go默认使用按值传递来传递参数,也就是传递参数的副本.在函数中对副本的值进行更改操作时,不会影响到原来的变量. 按引用传递其实也 ...

  6. go语言传参是值传递还是引用传递

    曾经在某次go面试中被面试官问到:"go中引用类型有哪些?",我答到:"slice,map,channel",面试官:"其实go没有引用类型,都是值类 ...

  7. go函数详解:函数定义、形参、返回值定义规范、函数内存分析、不支持重载、支持可变参数、基本数据类型和数组默认都是值传递的、支持自定义数据类型、函数返回值命名

    引入 [1]为什么要使用函数: 提高代码的复用型,减少代码的冗余,代码的维护性也提高了 [2]函数的定义: 为完成某一功能的程序指令(语句)的集合,称为函数. [3]基本语法 func 函数名(形参列 ...

  8. golang slice map扩容

    golang slice 扩容 操作系统预分配的内存规格 byte 8 16 32 64 80 96 112- 先求出当前切片容量x,求出append追加后的容量 y 判断 x*2 和y 的关系 1 ...

  9. golang slice 详解

    一.数组切片的使用: func main() {//1.基于数组创建数组切片var array [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}var ...

最新文章

  1. 宿州市人力资源和社会保障局数据保护及容灾系统方案公示
  2. 2019年上海市数学建模讲座笔记(2)概率统计模型
  3. Redis 如何保持和 MySQL 数据一致
  4. 纯c语言实现动态分配多维数组的方法
  5. python变量输出到文件_使用函数将多个变量写入文件
  6. 最美的十大精典爱情句子
  7. Android扩展类方法,Android 扩展 uni小程序SDK 原生能力
  8. 吴恩达机器学习总结四:Octave语法
  9. 深入Scripting Runtime Library
  10. 【matlab】访问结构体内部元素
  11. c语言的编译器vs2019的安装及简单实用
  12. html自动登录网页,简单网页登陆代码html
  13. avc 转 hevc
  14. 去除马赛克,有办法了 附运行教程
  15. 【5G/4G】NAS与AS层 完整性保护与加密算法系列文章
  16. PlayStation Now比您想象的要好
  17. 这些行业已经开始用数据挖掘了,我们的前途光明
  18. 智能存储 | 视频 DNA ,独一无二的安全标识
  19. Javascript特效之可翻阅上一条下一条的动态文字
  20. 【力扣Hot100】155. 最小栈

热门文章

  1. 为什么你应该尝试@reach/router
  2. 静态页面如何实现 include 引入公用代码
  3. ie 浏览器布局中的 offset
  4. 题解 P5259【欧稳欧再次学车】
  5. matplotlib绘制饼状图
  6. 【腾讯Bugly干货分享】Android内存优化总结实践
  7. SpringMVC学习笔记整理
  8. 拓扑排序最长链-P3119 [USACO15JAN]草鉴定Grass Cownoisseur
  9. memcpy、memmove、memset、memchr、memcmp、strstr详解
  10. [转载] Python3网络爬虫