切片相关基础内容

//切片

切片声明和初始化: 原文地址: https://www.liwenzhou.com/posts/Go/06_slice/

//切片
func main() {
	var a []string              //声明一个切片.
	var b = []int{}             //声明一个整型切片,并初始化
	var c = []bool{false, true} //声明一个布尔值类型切片并初始化
	fmt.Println(a, b, c)        //打印切片内容.[] [] [false true]
	fmt.Println(a == nil)       //true
	fmt.Println(b == nil)       //false
	fmt.Println(c == nil)       //false
	//fmt.Println(c ==d)  //切片是引用类型,不支持直接比较,只能和nil进行比较.

通过数组生成切片

func main() {
	a := [6]int{1, 2, 3, 4, 5, 6}
	s := a[1:4]
	fmt.Println(s, len(s), cap(s))
	//为了方便期间,可以省略切片表达式中的任何索引,省略了low则默认为0,省略了high则默认为切片操作数的长度
	s1 := a[2:] //表示从第二个元素到最后
	s2 := a[:3] //表示从第0个元素到底2个元素
	s3 := a[:] //表示从0个元素到最后
	fmt. Println(s,s1,s2,s3)
}
func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]
	fmt.Printf("s : %v len(s):%v  cap(s): %v\n", s, len(s), cap(s))
	s2 := s[3:4]
	fmt.Printf("s2:%v len(s2):%v cap(s2):%v\n", s2, len(s2), cap(s2))
}

切片长度和容量

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	t := a[1:3:5] //表示t切片从2到3,容量是5 这里长度默认值的个数,容量是指定的.
	fmt.Printf("t:%v len(t):%v cap(t):%v\n", t, len(t), cap(t))

}
输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_main_go.exe #gosetup
t:[2 3] len(t):2 cap(t):4

切片之间的判断

func main() {
	a := make([]int, 2, 10) //初始化分配了10个容量空间(可以动态扩容)
	fmt.Println(a)          //初始化没有加入数据,所以切片内是[0,0]
	fmt.Println(len(a))     //计算切片长度 2
	fmt.Println(cap(a))     //计算切片容量  10
	//切片的本质就是对底层数组的封装,它包含了三个信息:1,底层数组的指针,2切片长度,3.切片容量
	//判断切片是否为空
	//检查切片是否为空,强势中使用len(s) ==0 来判断.而不应该使用s==nil .没有长度表示为空.
	//切片之间不能比较,我们不能使用==来判断操作符来判断两个切片是否含有全部相等元素.切片的比较只能跟nil进行比较.
	//一个nil值的切片没有底层数组,一个nil值得切片长度和容量都是0,但是我们不能说一个长度和容量为0的切片与一个nil的切片相等.
	var s1 []int
	fmt.Println(s1, len(s1), cap(s1))
	s2 := []int{}
	fmt.Println(s2, len(s2), cap(s2))
	s3 := make([]int, 0)
	fmt.Println(s3, len(s3), cap(s3))
	switch {
	case s1 == nil:
		fmt.Println("s1==nil")
	case s1 != nil:
		fmt.Println("s1 !=nil")
	}
	switch {
	case s2 == nil:
		fmt.Println("s2==nil")
	case s2 != nil:
		fmt.Println("s2 != nil")
	}
	switch {
	case s3 == nil:
		fmt.Println("s3 ==nil")
	case s3 != nil:
		fmt.Println("s3 !=nil")
	}

}

输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[0 0]
2
10
[] 0 0
[] 0 0
[] 0 0
s1==nil
s2 != nil
s3 !=nil

从结果上看三个切片的初始值都是0,0但是其中s2,s3 的底层数组是nil.所以要判断一个切片是否是空的,要是用len(s) == 0来判断,不应该使用s == nil来判断

切片的赋值拷贝

//切片值拷贝
func main() {
	s1 := make([]int, 3)
	s2 := s1
	s2[0] = 100
	fmt.Println(s1) //100 0 0
	fmt.Println(s2) //100 0 0

}

相同切片的引用使用的是同一个底层数组,所以改变的也是同一个层数组的值,这里不需要进行指针的修改,
输出结果
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[100 0 0]
[100 0 0]

切片的遍历

//切片的遍历
func main() {
	s := []int{1, 3, 5}
	for i := 0; i < len(s); i++ {
		fmt.Println(i, s[i])
	}
	fmt.Println("-----分割线------")
	for index, value := range s {
		fmt.Println(index, value)
	}

}

这里遍历的结果返回两个值,i,s[i]表示切片的索引和值,与第二次遍历返回的index,value结果相同.
输出结果
C:\Users\34826\AppData\Local\Temp\___go_build_main_go.exe #gosetup
0 1
1 3
2 5
-----分割线------
0 1
1 3
2 5

为append方法为切片添加元素

//为切片动态添加元素
func main() {
	var s []int //表示s初始化一个int类型的切片,但是切片中没有内容.所以这种情况表示内存地址已经分配,可以直接追加赋值其他元素.
	s = append(s, 1)
	s = append(s, 2, 3, 4)
	s2 := []int{5, 6, 7}
	s = append(s, s2...) //这里表示将s2切片传到s当中,但是传递的方式是以单个元素的方式进行传递,与下面的结果相同
	//s = append(s , s2[0],s2[1],s2[2])
	fmt.Println(s)

}

输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[1 2 3 4 5 6 7]
注意:通过var声明的零值切片可以在append()函数直接使用,无需初始化。

切片copy

//切片copy
func main() {
	//copy(destSlice, srcSlice []T)
	//srcSlice: 数据来源切片
	//destSlice: 目标切片
	var a = []int{1, 2, 3, 4, 5}
	//var c = []int{5, 5}  //这里表示c切片只有两个元素.与make进行的初始化是不同的.如果使用这种方式初始化的话那最终在进行copy过程中只能将前两个值copy到c中.
c := make([]int,5,5) //初始化切片,并且切片长度和容量都是5
	copy(c, a)
	fmt.Println(a)
	fmt.Println(c)
	c[0] = 1000
	fmt.Println(a)
	fmt.Println(c)
}

输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[1 2 3 4 5]
[1 2 3 4 5]
[1 2 3 4 5]
[1000 2 3 4 5]


这里的输出结果看切片a和切片c之间是没有影响的,

从切片中删除元素

func main() {
	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	a1 := a
	fmt.Println(a1)
	a = append(a[:2], a[3:]...) //这里表示将a[3:]到最后的所有数值都拆开并追加到a[:2]中
	a2 := a
	fmt.Println(a2)
}

输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_main_go.exe #gosetup
[30 31 32 33 34 35 36 37]
[30 31 33 34 35 36 37]

这里使用append将不需要的元素从原始切片中剔除.(推测.)并且使用的貌似还是原来的内存地址
//练习题 请写出下面代码的输出结果。
func main() {
	var a = make([]string, 5, 10) //初始化是有5个元素,并且是5个空值,
	for i := 0; i < 10; i++ {
		a = append(a, fmt.Sprintf("%v", i)) //追加循环的数子到切片中,但是 原本的空值是存在的,(此时因为切片容量为10,装不下15个元素,
		//// 所以会进行一次扩容到20,并且因为原始切片是string类型,所以这里使用Sprintf进行转换了一次.
	}
	fmt.Println(a) //[     0 1 2 3 4 5 6 7 8 9]
}


输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[     0 1 2 3 4 5 6 7 8 9]  //这里前面有五个空值(不是空格)
//作业2 使用sort包对 数组var a = [...]int{3, 7, 8, 9, 1 }进行排序
func main() {
	a := [...]int{3, 7, 8, 9, 1}
	fmt.Println(a)
	sort.Ints(a[:]) //这里要注意,sort传入的是一个切片类型,要将原来的数组转换成切片类型进行传入.在进行排序.
	fmt.Println("排序结果:", a)

}

输出结果:
C:\Users\34826\AppData\Local\Temp\___go_build_code_oldboy_com_studygolang_05lesson5_lesson1.exe #gosetup
[3 7 8 9 1]
排序结果: [1 3 7 8 9]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值