go语言渐入佳境[13]-切片-创新互联

切片

1、切片可以修改大小
2、切片的拷贝不是单纯值的拷贝,一个切片指向了一个数组

创新互联客户idc服务中心,提供西信服务器托管、成都服务器、成都主机托管、成都双线服务器等业务的一站式服务。通过各地的服务中心,我们向成都用户提供优质廉价的产品以及开放、透明、稳定、高性价比的服务,资深网络工程师在机房提供7*24小时标准级技术保障。

切片的声明

1
2
3
4
5
6
7
//切片的声明1  //nil
var slice1 []int  

//切片的声明2
var slice2 []int = make([]int,5)
var slice3 []int = make([]int,5,7)
numbers:= []int{1,2,3,4,5,6,7,8}

切片截取

1
2
3
4
5
6
7
8

numbers:= []int{1,2,3,4,5,6,7,8}
//从下标1一直到下标4,但是不包括下标4
numbers1 :=numbers[1:4]
//从下标0一直到下标3,但是不包括下标3
numbers2 :=numbers[:3]
//从下标3一直到结束
numbers3 :=numbers[3:]

切片截取例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

import "fmt"

//1、切片可以修改大小

//2、切片的拷贝不是单纯值的拷贝,一个切片指向了一个数组


//切片的声明1
var slice1 []int

//切片的声明2
var slice2 []int = make([]int,5)
var slice3 []int = make([]int,5,7)

func main(){


slice4 := make([]int,5)
slice5 := make([]int,5,7)

slice6 := make([]int,0)


fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice4),cap(slice4),slice4)
fmt.Printf("len=%d,cap=%d,slice=%v",len(slice5),cap(slice5),slice5)


if slice4 ==nil{
fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice4),cap(slice4),slice4)

}
// slice6 := make([]int,0)不为nil
if slice6 !=nil{
fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice6),cap(slice6),slice6)

}
//var slice1 []int为nil
if slice1 ==nil{
fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice1),cap(slice1),slice1)

}

sliceTest()
}

//截取
func sliceTest(){
numbers:= []int{1,2,3,4,5,6,7,8}
printSliceInfo(numbers)

numbers1 :=numbers[1:4]
printSliceInfo(numbers1)


numbers2 :=numbers[:3]
printSliceInfo(numbers2)

numbers3 :=numbers[3:]
printSliceInfo(numbers3)
}
//打印切片
func printSliceInfo(x []int){

fmt.Printf("len=%d,cap=%d,slice=%v\n",len(x),cap(x),x)
}

利用切片截取进行删除

1
2
3
4
5
6
7
8
9
10
11

// 切片删除
// 删除第一个元素
numbers = numbers[1:]  

// 删除最后一个
numbers = numbers[:len(numbers)-1]

//删除中间一个元素
a := int(len(numbers) / 2)
numbers = append(numbers[:a], numbers[a+1:]...)

切片与数组的拷贝对比

数组的拷贝是副本拷贝。对于副本的改变不会影响到
切片的拷贝很特殊,切片的副本仍然指向了相同的数组。所以,对于副本的修改会影响到相同的数组。

下面的例子说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
//数组是值类型
a := [4]int{1, 2, 3, 4}

//切片是引用类型
b := []int{100, 200, 300}

c := a
d := b

c[1] = 200
d[0] = 1

fmt.Println("a=", a, "c=", c)
//c[1 200 3 4] a[1 2 3 4]
fmt.Println("b=", b, "d=", d)
//d[1 200 300]  b[1 200 300]
}

append添加元素

1
2
3
4
5
6
7
8
9
10
11
12
13
numbers := make([]int, 0, 20)


//append一个元素
numbers = append(numbers, 0)

//append多个元素
numbers = append(numbers, 1, 2, 3, 4, 5, 6, 7)


//append添加切片
s1 := []int{100, 200, 300, 400, 500, 600, 700}
numbers = append(numbers, s1...) //[0 1 2 3 4 5 6 7 100 200 300 400 500 600 700]

copy

毫无疑问,创建新的目标切片就会有新的指向的数组。数组的copy是对于不同的数组的值的拷贝

1
2
3
4
5
//创建目标切片
numbers1 := make([]int, len(numbers), cap(numbers)*2)

// 将numbers的元素拷贝到numbers1中
count := copy(numbers1, numbers)

例子2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main

import "fmt"

func main() {
fmt.Println("1、--------------")
//var numbers []int
numbers := make([]int, 0, 20)


//append一个元素
numbers = append(numbers, 0)
printSlice("numbers:", numbers) //[0]

//append多个元素
numbers = append(numbers, 1, 2, 3, 4, 5, 6, 7)
printSlice("numbers:", numbers) //[0 1 2 3 4 5 6 7]

//append添加切片
s1 := []int{100, 200, 300, 400, 500, 600, 700}
numbers = append(numbers, s1...) //[0 1 2 3 4 5 6 7 100 200 300 400 500 600 700]
printSlice("numbers:", numbers)





fmt.Println("2、--------------")
// 切片删除
// 删除第一个元素
numbers = numbers[1:]
printSlice("numbers:", numbers) //[ 1 2 3 4 5 6 7 100 200 300 400 500 600 700]

// 删除最后一个
numbers = numbers[:len(numbers)-1]
printSlice("numbers:", numbers) //[ 1 2 3 4 5 6 7 100 200 300 400 500 600]

//删除中间一个元素
a := int(len(numbers) / 2)
fmt.Println("中间下标:", a)
numbers = append(numbers[:a], numbers[a+1:]...)
printSlice("numbers:", numbers) //[1 2 3 4 5 6 100 200 300 400 500 600]




fmt.Println("3、--------------")
//创建目标切片
numbers1 := make([]int, len(numbers), cap(numbers)*2)

// 将numbers的元素拷贝到numbers1中
count := copy(numbers1, numbers)
fmt.Println("拷贝的个数:", count)
printSlice("numbers1:", numbers1)

//拷贝的两个切片是否有关联
numbers[0] = 99
numbers1[len(numbers1)-1] = 100

printSlice("numbers", numbers)
printSlice("numbers1", numbers1)

}

func printSlice(name string, x []int) {
fmt.Print(name, "\t")
fmt.Printf("地址:%p \t len=%d \t cap=%d \t value=%v \n", x, len(x), cap(x), x)
}

疯狂切片原理

理解了下面代码到底输出什么,就理解了切片的原理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

func f(s []string, level int) {
       if level > 5 {
              return
       }
       s = append(s, fmt.Sprint(level))
       f(s, level+1)
       fmt.Println("level:", level, "slice:", s)
}

func main() {
       f(nil, 0)
}

输出结果:

1
2
3
4
5
6
level: 5 slice: [0 1 2 3 4 5]
level: 4 slice: [0 1 2 3 4]
level: 3 slice: [0 1 2 3]
level: 2 slice: [0 1 2]
level: 1 slice: [0 1]
level: 0 slice: [0]

参考资料:
https://dave.cheney.net/2018/07/12/slices-from-the-ground-up

  • 本文链接: https://dreamerjonson.com/2018/11/20/golang-13-slice/

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!

go语言渐入佳境[13]-切片

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


文章名称:go语言渐入佳境[13]-切片-创新互联
文章链接:http://scyanting.com/article/gisoc.html