//切片
切片声明和初始化: 原文地址: 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]
257

被折叠的 条评论
为什么被折叠?



