golang slice 作为参数值传递情况说明

这篇具有很好参考价值的文章主要介绍了golang slice 作为参数值传递情况说明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

golang 中引用类型有:slice、map、interface、channel
golang所有类型在函数中都是值传递,这个跟上面golang中有的数据类型为引用类型并不冲突,用下面四个slice实例帮助理解

// 例子 1
func fn(s []int) {
    s[0] = 3
}

func main() {
	slice := []int{1,2}
	fmt.Printf("before fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("before fn slice data:",slice)
	fn(slice)
	fmt.Printf("after fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("after fn slice data:",slice)
}

// 输出结果
// before fn slice len:2, cap:2, add:0xc000132b00before fn slice data: [1 2]
// after fn slice len:2, cap:2, add:0xc000132b00after fn slice data: [3 2]

说明: main 函数中slice[0]说明 fn 函数里面的修改,也改变函数外的值,这跟slice为引用类型的缘故

// 例子 2
func fn(s []int) {
    s[0] = 3
    s = append(s, 4)
    fmt.Printf("fn in slice len:%d, cap:%d, add:%p", len(s), cap(s), s)
    fmt.Println("fn in slice data:", s)
}

func main() {
	slice := []int{1,2}
	fmt.Printf("before fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("before fn slice data:",slice)
	fn(slice)
	fmt.Printf("after fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("after fn slice data:",slice)
}

// 输出结果
// before fn slice len:2, cap:2, add:0xc000026ba0before fn slice data: [1 2]
// fn in slice len:3, cap:4, add:0xc0000244c0fn in slice data: [3 2 4]
// after fn slice len:2, cap:2, add:0xc000026ba0after fn slice data: [3 2]

说明:slice[0] 被修改原因见例1,fn中append的值没有带出来,这里是slice原始分配的空间为2,append导致空间不足,分配新地址,fn外地址不变,导致append的值函数外获取不到??那就分配足够的空间见例3

// 例子 3
func fn(s []int) {
    s[0] = 3
    s = append(s, 4)
    fmt.Printf("fn in slice len:%d, cap:%d, add:%p", len(s), cap(s), s)
    fmt.Println("fn in slice data:", s)
}

func main() {
	slice := make([]int, 0, 4)
	// slice = []int{1,2} // 直接赋值会修改slice的地址
	slice = append(slice,1,2)
	fmt.Printf("before fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("before fn slice data:",slice)
	fn(slice)
	fmt.Printf("after fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("after fn slice data:",slice)
}

// 输出结果
// before fn slice len:2, cap:2, add:0xc000026ba0before fn slice data: [1 2]
// fn in slice len:3, cap:4, add:0xc0000244c0fn in slice data: [3 2 4]
// after fn slice len:2, cap:2, add:0xc000026ba0after fn slice data: [3 2]

说明:slice 分配了足够的空间发现,fn内部append依旧没有生效,观察地址发现fn内部的地址和函数外的地址不一致,因为fn方法参数为切片,而不是切片数组,slice 底层结构为len、cap和指向存储位置的地址,slice 在函数间传递,指向存储位置的地址的指针是一致,但是不同函数的slice不是同一个对下个,对应的len、cap是不一致的

// 例子 4
func fn(s *[]int) {
    (*s)[0] = 3
    *s = append(*s, 4)
}

func main() {
	slice := make([]int, 0, 4)
	// slice = []int{1,2} // 直接赋值会修改slice的地址
	slice = append(slice,1,2)
	fmt.Printf("before fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("before fn slice data:",slice)
	fn(&slice)
	fmt.Printf("after fn slice len:%d, cap:%d, add:%p", len(slice), cap(slice), slice)
	fmt.Println("after fn slice data:",slice)
}

// 输出结果
// before fn slice len:2, cap:2, add:0xc000026b80before fn slice data: [1 2]
// after fn slice len:3, cap:4, add:0xc0000244a0after fn slice data: [3 2 4]

说明:函数间的参数传递改为指针,保证函数内外完全是同一个值,故函数内的修改和append函数外都能获取到文章来源地址https://www.toymoban.com/news/detail-613472.html

到了这里,关于golang slice 作为参数值传递情况说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Golang】Golang进阶系列教程--Go 语言切片是如何扩容的?

    在 Go 语言中,有一个很常用的数据结构,那就是切片(Slice)。 切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。 切片是一种引用类型,它有三个属性:指针,长度和容量。 底层源码定义如下: 指针: 指向

    2024年02月14日
    浏览(70)
  • golang无需创建新切片

    在 Go 语言中,`append(b, 0)[:len(b)]` 是一种常见的用法,用于在切片 `b` 后追加一个元素,并返回旧切片的前 `len(b)` 个元素。 这种用法的目的是将一个新元素追加到切片中,并确保切片的长度保持不变。具体步骤如下: 1. `append(b, 0)`:通过 `append` 函数将元素 `0` 追加到切片 `b`

    2024年02月11日
    浏览(37)
  • golang字符串切片去重

    函数的功能是从输入的字符串切片中去除重复的元素,并返回去重后的结果。具体的实现逻辑如下: 创建一个空的结果切片 result ,用于存储去重后的字符串。 创建一个临时的map tempMap ,用于存放不重复的字符串。map的键是字符串,值是字节类型。 遍历输入的字符串切片

    2024年02月12日
    浏览(39)
  • golang 基于数组、切片、链表实现队列

    数组 切片 链表 链表加锁实现线程安全 cas 实现 无锁队列

    2024年02月04日
    浏览(42)
  • 为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

    Fasthttp 是一个高性能的 Golang HTTP 框架,它在设计上做了许多优化以提高性能。其中一个显著的设计选择是使用 slice 而非 map 来存储数据,尤其是在处理 HTTP headers 时。 为什么呢? 本文将从简单到复杂,逐步剖析为什么 Fasthttp 选择使用 slice 而非 map,并通过代码示例解释这一

    2024年01月22日
    浏览(49)
  • 【GoLang】【工具分享】1、根据 JsonTag 对 slice 进行稳定排序(不支持嵌套)

    后端返回 List 列表中的 Json 序列化结构到前端,其中包含许多字段,业务需求可以按照某个字段对列表数据做 升/降序排序。 前端将后端返回的 Json 及排序方向作为参数传递至后端即可,后端根据 Json 排序找到对应的 JsonTag 后,采用反射找到字段,再写自定义排

    2024年02月12日
    浏览(39)
  • 关于切片参数传递的问题

    前言:在 Golang 中函数之间传递变量时总是以值的方式传递的,无论是 int,string,bool,array 这样的内置类型(或者说原始的类型),还是 slice,channel,map 这样的引用类型,在函数间传递变量时,都是以值的方式传递,也就是说传递的都是值的副本。 在使用ioutil的ReadAll方法时查看了

    2024年02月06日
    浏览(35)
  • Golang教程一(环境搭建,变量,数据类型,数组切片map)

    目录 一、环境搭建 1.windows安装 2.linux安装  3.开发工具 二、变量定义与输入输出 1.变量定义 2.全局变量与局部变量 3.定义多个变量 4.常量定义 5.命名规范 6.输出 格式化输出 7.输入  三、基本数据类型 1.整数型 2.浮点型 3.字符型 4.字符串类型 转义字符 多行字符串 5.布尔类型

    2024年04月16日
    浏览(49)
  • Golang 卡码网55 右旋字符串 切片拷贝问题补充

    右旋字符串 55卡码网 关于go中切片的拷贝问题: 通过[:]的方式进行赋值的方式,如b:=a[:2],由于其共享底层的数组,所以说修改其中之一,另一个也是受影响的,为 浅拷贝 切片如果想要实现深拷贝,需要使用** copy **

    2024年01月22日
    浏览(36)
  • 【Golang】golang中http请求的context传递到异步任务的坑

    在golang中,context.Context可以用来用来设置截止日期、同步信号,传递请求相关值的结构体。 与 goroutine 有比较密切的关系。 在web程序中,每个Request都需要开启一个goroutine做一些事情,这些goroutine又可能会开启其他的 goroutine去访问后端资源,比如数据库、RPC服务等,它们需要访

    2024年02月08日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包