golang中的append函数详解

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

内容简介:参考网址: 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


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

查看所有标签

猜你喜欢:

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

Programming PHP

Programming PHP

Rasmus Lerdorf、Kevin Tatroe、Peter MacIntyre / O'Reilly Media / 2006-5-5 / USD 39.99

Programming PHP, 2nd Edition, is the authoritative guide to PHP 5 and is filled with the unique knowledge of the creator of PHP (Rasmus Lerdorf) and other PHP experts. When it comes to creating websit......一起来看看 《Programming PHP》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具