golang中的append函数详解

栏目: Go · 发布时间: 6年前

内容简介:参考网址: https://studygolang.com/articles/10924
  1. append函数是用来在slice末尾追加一个或者多个元素。
  2. 当追加元素时,发现slice的 len>cap 时,会重新开辟一个 2*cap 的内存空间去存储追加过元素的slice。
  3. 如果追加元素后slice的 len<=cap ,则append返回的新生成的slice的内存地址 依旧 是传入的slice参数的内存地址。
testSlice := make([]int, 0)
	testSlice = append(testSlice, 0)
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice)
	//len: 1, cap: 1, data:[0]
	fmt.Printf("testSlice地址:%p \n", &testSlice[0])
	//testSlice地址:0xc04203c1d0

	testSlice = append(testSlice, 1)
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice)
	//len: 2, cap: 2, data:[0 1]
	//因为cap长度不够,所以重新申请一个2*cap长度的内存空间,将内容拷贝到2倍cap的内存中
	fmt.Printf("testSlice地址:%p \n", &testSlice[0])
	//testSlice地址:0xc04203c220
	//testSlice的内存地址变化了

	testSlice = append(testSlice, 2)
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice)
	//len: 3, cap: 4, data:[0 1 2]
	fmt.Printf("testSlice地址:%p \n", &testSlice[0])
	//testSlice地址:0xc042042480

	testSlice = append(testSlice, 3)
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice)
	//len: 4, cap: 4, data:[0 1 2 3]
	fmt.Printf("testSlice地址:%p \n", &testSlice[0])
	//testSlice地址:0xc042042480
	//因为cap空间足够用,所以继续在原来的内存地址上追加数据

	testSlice1 := append(testSlice, 4)
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice)
	//len: 4, cap: 4, data:[0 1 2 3]
	fmt.Printf("testSlice地址:%p \n", &testSlice[0])
	//testSlice地址:0xc042042480
	//testSlice的数据不变

	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice1), cap(testSlice1), testSlice1)
	//len: 5, cap: 8, data:[0 1 2 3 4]
	fmt.Printf("testSlice1地址:%p \n", &testSlice1[0])
	//testSlice1地址:0xc0420440c0
	//新生成的testSlice1内存地址变化了

	testSlice2 := append(testSlice1, 5)

	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice1), cap(testSlice1), testSlice1)
	//len: 5, cap: 8, data:[0 1 2 3 4]
	fmt.Printf("testSlice1地址:%p \n", &testSlice1[0])
	//testSlice1地址:0xc0420440c0
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice2), cap(testSlice2), testSlice2)
	//len: 6, cap: 8, data:[0 1 2 3 4 5]
	fmt.Printf("testSlice2地址:%p \n", &testSlice2[0])
	//testSlice2地址:0xc0420440c0
	//在这里可以看到testSlice1和testSlice2的内存地址是一样的

	p := unsafe.Pointer(&testSlice1[4])
	q := uintptr(p) + 8
	t := (*int)(unsafe.Pointer(q))
	fmt.Println("testSlice1可以拿到testSlice2的第五个元素值:", *t)
	//testSlice1可以拿到testSlice2的第五个元素值: 5

	testSlice2[0] = 99999
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice1), cap(testSlice1), testSlice1)
	//len: 5, cap: 8, data:[99999 1 2 3 4]
	fmt.Printf("testSlice1地址:%p \n", &testSlice1[0])
	//testSlice1地址:0xc0420440c0
	fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice2), cap(testSlice2), testSlice2)
	//len: 6, cap: 8, data:[99999 1 2 3 4 5]
	fmt.Printf("testSlice2地址:%p \n", &testSlice2[0])
	//testSlice2地址:0xc0420440c0
	//修改testSlice2的值同时会改变testSlice1中的值
	//当然testSlice1一般不能访问testSlice2中的第6个元素,因为testSlice1的len是5
	//但是可以通过上面的方法访问,通过操作内存地址来访问

参考网址: https://studygolang.com/articles/10924


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

复杂网络理论及其应用

复杂网络理论及其应用

汪小帆、李翔、陈关荣 / 清华大学出版社 / 2006 / 45.00元

国内首部复杂网络专著 【图书目录】 第1章 引论 1.1 引言 1.2 复杂网络研究简史 1.3 基本概念 1.4 本书内容简介 参考文献 第2章 网络拓扑基本模型及其性质 2.1 引言 2.2 规则网络 2.3 随机图 2.4 小世界网络模型 2.5 无标度网络模型 ......一起来看看 《复杂网络理论及其应用》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具