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


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

查看所有标签

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

秩序之美

秩序之美

Vinh / 人民邮电 / 2011-5 / 35.00元

怎样才能设计出简洁大方而不落于俗套的超人气网站?纽约时报网站的资深设计师Khoi Vinh在这《秩序之美——网页中的网格设计》一书中将为你揭示其中的奥秘。   《秩序之美——网页中的网格设计》将源自传统平面设计、被众多平面设计大师推崇的网格设计方法应用于网页设计,向读者详细介绍了网格设计成熟而经典的设计模式,并以整个网站的设计为例,对工作流程、设计工具和方法进行了系统而全面的介绍,手把手教读......一起来看看 《秩序之美》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具