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 语言切片是如何扩容的?

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

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

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

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

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

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

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

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

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

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

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

    为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

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

    2024年01月22日
    浏览(11)
  • 关于切片参数传递的问题

    关于切片参数传递的问题

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

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

    Golang教程一(环境搭建,变量,数据类型,数组切片map)

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

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

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

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

    【Golang】golang中http请求的context传递到异步任务的坑

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

    2024年02月08日
    浏览(14)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包