Go的切片及用append()给切片添加元素

Go的切片:

package main

import "fmt"

//切片slice,是对数组的一个连续片段的引用,所以切片是一个引用类型,像python中list类型


//Go语言中切片的内部结构包含地址,大小和容量,切片一般用于快速地操作一块数据集合


//从数组或切片生成新的切片

//格式:slice[开始位置:结束位置]
//slice:表示目标切片对象;开始位置:对应目标的切片对象的索引;结束位置:对应目标切片结束的索引

//根据索引位置取切片 slice 元素值时,取值范围是(0~len(slice)-1),超界会报运行时错误,生成切片时,结束位置可以填写 len(slice) 但不会报错。
func main()  {
	var a=[3]int{1,2,3}
	//从切片开始索引到不包含结束位置对应的索引
	fmt.Println(a,a[1:3])  //[1 2 3] [2 3]
	//取索引为0~2	不包含索引为2的
	fmt.Println(a[:2])	   //[1 2]
	//取索引为1且包含1的后面所有元素
	fmt.Println(a[1:])     //[2 3]

	slice()

	makesilce()
}

//声明新的切片
//声明新的切片后,可以使用 append() 函数向切片中添加元素。

func slice()  {
	//声明字符串切片
	var strList[]string
	//声明整型切片
	var numList[]int
	//声明一个空切片
	var numListEmpty=[]int{}
	//输出3个切片
	fmt.Println(strList,numList,numListEmpty)   //[] [] []
	//输出3个切片大小
	fmt.Println(len(strList),len(numList),len(numListEmpty))  //0 0 0
	//切片判定空的结果
	//声明但未使用的切片的默认值是 nil,strList 和 numList 也是 nil,所以和 nil 比较的结果是 true。
	//切片是动态结构,只能与 nil 判定相等,不能互相判定相等。
	fmt.Println(strList==nil)  //true
	fmt.Println(numList==nil)  //true
	fmt.Println(numListEmpty==nil) //false:numListEmpty 已经被分配了内存,只是还没有元素
}



//使用make()函数构造切片:make( []Type, size, cap )
//其中 Type 是指切片的元素类型,size 指的是为这个类型分配多少个元素,cap 为预分配的元素数量,这个值设定后不影响 size,只是能提前分配空间,降低多次分配空间造成的性能问题。
//使用 make() 函数生成的切片一定发生了内存分配操作,但给定开始与结束位置(包括切片复位)的切片只是将新的切片结构指向已经分配好的内存区域,设定开始与结束位置,不会发生内存分配操作。
func makesilce()  {
	a:=make([]int,2,20)
	fmt.Println(a)
}

append方法

package main

import (
	"fmt"
)
//append()为切片添加元素
//切片(slice)是对数组的一个连续片段的引用,所以切片是一个引用类型,像python中的list对象
func main()  {
	var a []int
	a=append(a,1) //追加一个元素
	a=append(a,2,3,4)  //追加多个元素,手动解包
	fmt.Println(a) //[1 2 3 4]
	//给a追加一个切片,切片需要解包
	a=append(a,[]int{1,2,3}...)
	fmt.Println(a)//[1 2 3 4 1 2 3]
	List1()

	Frist()

	Chian()

}


//切片在使用append函数为切片添加元素时,空间不足时会自动扩容

func List1()  {
	//声明切片
	var list[]int
	for i:=0;i<10 ;i++  {
		list=append(list,i)
		//println会根据你输入格式原样输出,printf需要格式化输出并带输出格式;
		//%d以10为基数
		//%p以16为基础的表示法,前导0x
		fmt.Printf("len: %d  cap: %d  pointer: %p\n",len(list),cap(list),list)
	}
}

/*
长度    容量     内存指针
len: 1  cap: 1  pointer: 0xc00008a080
len: 2  cap: 2  pointer: 0xc00008a0a0
len: 3  cap: 4  pointer: 0xc00008c060
len: 4  cap: 4  pointer: 0xc00008c060
len: 5  cap: 8  pointer: 0xc000090080
len: 6  cap: 8  pointer: 0xc000090080
len: 7  cap: 8  pointer: 0xc000090080
len: 8  cap: 8  pointer: 0xc000090080
len: 9  cap: 16  pointer: 0xc000092000
len: 10  cap: 16  pointer: 0xc000092000
随着添加元素的增加,切片长度len不等于容量cap,内存也随之变化
 */


//在切片开头添加元素

func Frist()  {
	//在切片开头添加元素一般都会导致内存的重新分配,而且会导致已有元素全部被复制 1 次,
	// 因此,从切片的开头添加元素的性能要比从尾部追加元素的性能差很多。
	var a=[]int{1,2,3,4}
	a=append([]int{0},a...)  //在开头添加1个元素
	fmt.Println(a)//[0 1 2 3 4]
	a=append([]int{4,5,6,7},a...)  //在开头添加一个切片
	fmt.Println(a)//[4 5 6 7 0 1 2 3 4]
}

//因为 append 函数返回新切片的特性,所以切片也支持链式操作,
// 我们可以将多个 append 操作组合起来,实现在切片中间插入元素



//切片的链式操作
func Chian()  {
	var b =[]int{1,2,3,4,5}
	//每个添加操作中的第二个 append 调用都会创建一个临时切片,并将 a[i:] 的内容复制到新创建的切片中,
	// 然后将临时创建的切片再追加到 a[:i] 中。
	//先在b[2:]开头处添加一个元素,然后再将整个切片添加到b[:2]后边
	b=append(b[:2],append([]int{9},b[2:]...)...)  //在第i个位置插入x
	fmt.Println(b)  //[1 2 9 3 4 5]
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值