go递归函数如何传递数组切片slice
数组切片slice这个东西看起来很美好,真正用起来会发现有诸多的不爽。
第一,数组、数组切片混淆不清,使用方式完全一样,有时候一些特性又完全不一样,搞不清原理很容易误使用。
第二,数组切片的append操作,每次对slice append操作,都返回一个新的slice的引用,对slice的引用没法保持,这样在函数传递slice的情况下append,在调用函数的上下文中看不到slice append的效果。如果想要这种方式凑效,不得不另辟蹊径。本文主要说一下如何解决这个窘境的方法。
函数传递slice存在什么问题?
func sliceModify(slice []int) {
// slice[0] = 88
slice = append(slice, 6)
}
func main() {
slice := []int{1, 2, 3, 4, 5}
sliceModify(slice)
fmt.Println(slice)
}
输出:
[1 2 3 4 5]
问题所在:
虽然说数组切片在函数传递时是按照引用的语义传递的,比如说在sliceModify函数里面slice[0] = 88,在方法调用的上下文中,调用函数对slice引用的改表是看得见的。
但是在对slice进行append操作的时候,我们惊奇的发现,这次又不管用了。原因就是append操作会返回这个扩展了的slice的引用,必须让原引用重新赋值为新slice的引用,说白了就是,传递过来的这个指针原来指了内存中的A区域,A区域是原数组的真正所在。经过一次 append之后,要把这个指针改为指向B,B对应append后新的slice的引用。但是方法调用的上下文里的slice指针还是指向了老的A内存区域。
这个逻辑实在有些奇葩,这里我不得不再次吐槽append的设计。有人说这个问题好解决啊,只需要在sliceModify函数的返回值中把append后新的slice引用返回就好了。这样做当然是可以滴,但是像递归调用的函数就不好解决了。
下面就说一下这个问题的解决办法,方法也很简单,就是传递指针的指针。虽然有些绕,但是总算把问题解决了。当然也有其他的办法,比如按照java等语言的方式,自己实现一个ArrayList,在对可变数组扩展的时候,千万表改变引用了。
func sliceModify(slice *[]int) {
*slice = append(*slice, 6)
}
func main() {
slice := []int{1, 2, 3, 4, 5}
sliceModify(&slice)
fmt.Println(slice)
}
这次就可以输出预期的结果了:
[1 2 3 4 5 6]
递归调用的例子:
func insertTo10(arr *[]int) {
length := len(*arr)
if length == 10 {
return
}
*arr = append(*arr, length)
insertTo10(arr)
}
func main() {
arr10 := []int{}
insertTo10(&arr10)
fmt.Println(arr10)
}
还可以访问我树莓派上搭的博客地址:
go递归函数如何传递数组切片slice的更多相关文章
- go 数组(array)、切片(slice)、map、结构体(struct)
一 数组(array) go语言中的数组是固定长度的.使用前必须指定数组长度. go语言中数组是值类型.如果将数组赋值给另一个数组或者方法中参数使用都是复制一份,方法中使用可以使用指针传递地址. 声明 ...
- go语言之---数组(array)和切片(slice)
一.数组 1.什么是数组? 1.数组是一系列同一类型数据的集合 2.数组中包含的每个数据被称为数组元素 3.一个数组中包含的元素个数成为数组长度 4.数组的长度是固定的 5.一个数组可以由零个或者多个 ...
- Go 数组(array) & 切片(slice)
数组 数组是一组固定长度的序列 数组类型 数组的类型不仅和储存元素的类型有关,还和数组长度有关,不同长度的数组是不同的类型 不同类型的数组不能共用一个函数 func main() { var a [1 ...
- Go语言学习之4 递归&闭包&数组切片&map&锁
主要内容: 1. 内置函数.递归函数.闭包2. 数组与切片3. map数据结构4. package介绍 5. 排序相关 1. 内置函数.递归函数.闭包 1)内置函数 (1). close:主要用来关闭 ...
- go语言 类型:数组切片
初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针.数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针: 2.数组切片中的元素个数: 3.数组切 ...
- go语言中的数组切片:特立独行的可变数组
go语言中的数组切片:特立独行的可变数组 初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多.但是在使用了一段 ...
- Go语言学习笔记(三)数组 & 切片 & map
加 Golang学习 QQ群共同学习进步成家立业工作 ^-^ 群号:96933959 数组 Arrays 数组是同一种数据类型的固定长度的序列. 数组是值类型,因此改变副本的值,不会改变本身的值: 当 ...
- Golang 入门 : 切片(slice)
切片(slice)是 Golang 中一种比较特殊的数据结构,这种数据结构更便于使用和管理数据集合.切片是围绕动态数组的概念构建的,可以按需自动增长和缩小.切片的动态增长是通过内置函数 append( ...
- Go 灵活多变的切片Slice
我们知道数组定义好之后其长度就无法再修改,但是,在实际开发过程中,有时候我们并不知道需要多大的数组,我们期望数组的长度是可变的, 在 Go 中有一种数据结构切片(Slice) 解决了这个问题,它是可变 ...
随机推荐
- Angular 4 依赖注入
一.依赖注入 1. 创建工程 ng new myangular 2. 创建组件 ng g componet product1 3. 创建服务 ng g service shared/product 如 ...
- spring mvc 工作原理
SpringMVC的工作原理图: SpringMVC流程 1. 用户发送请求至前端控制器DispatcherServlet. 2. DispatcherServlet收到请求调用HandlerMa ...
- 【jmeter】jmeter测试手机app的服务器压力
具体步骤: 1.电脑启动jmeter 2.jmeter在测试计划新建线程组. 3.在工作台新建http代理服务器 4.配置HTTP代理服务器 5.设置IE代理到本地 6.手机wifi设置代理连接到PC ...
- 10个CSS+HOVER 的创意按钮
CSS hover 样式很简单,但是想创造出有意思.实用.有创意性的特效是很考验设计师的创意能力,所以设计达人每隔一段时间都会分享一些与鼠标点击.悬停的相关特效,以便大家获得更好的创造灵感. 今天我们 ...
- msql主从复制
Mysql数据库主从复制原理: 主库开启bin-log日志,同时生成IO线程.IO线程负责将用户写入数据库的sql语句记录在二进制日志bin-log,该记录过程可并发进行:生成标识号 server i ...
- Gitlab 项目上传
一,登陆gitab,新建reject Repository name: 仓库名称 Description(可选): 仓库描述介绍 Public, Private : 仓库权限(公开共享,私有或指定合作 ...
- Mybatis学习(1)
一.原生态jdbc程序存在的问题: mybatis框架原理.执行过程: 二.入门程序 完成入门程序的以下需求: 1.根据用户id(主键)查询用户信息: 2.根据用户名称模糊查询用户信息: 3.添加用户 ...
- (转!)大话websocket
邪正看眼鼻,真假看嘴唇,功名看气概,富贵看精神. ---曾国藩<冰鉴> 转自https://www.cnblogs.com/fuqiang88/p/5956363.html 原文http: ...
- Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(六)GameplayEffect的级别设置
本节的内容不难,权当是复习.如果没有完成前面的教程,请前往学习. 第一步:用一个csv文件表示级别数据,下图中的Hurt随级别1~7表示其损伤值在1~7级别时分别是-7,-14,-20等.写好之后关闭 ...
- 【Gearman学习笔记】分布式处理入门
1.首先,确保你已经安装了gearmand环境并且语言绑定(language binding)已经生效. 2.涉及到的各个部分: ServerThe server, gearmand, will co ...