Golang Slice切片

1. 切片的定义和初始化

  • 切片是基于数组类型的封装,非常灵活,可以自动扩容
  • 切片是真正意义上的动态数组,而且是一个引用类型,切片指向一个底层数组

定义切片

var 切片名[] 切片类型

创建切片方式

package main

import "fmt"

func main() {
	// 1. 声明切片
	var s1 []int
	if s1 == nil { // 只声明没有初始化,所以是nil
		fmt.Println("为空")
	} else {
		fmt.Println("不为空")
	}

	// 2. := 自动推导
	s2 := []int{}

	// 3. make(切片类型, 长度, 容量)
	// 容量是可选的
	var s3 []int = make([]int, 0)

	fmt.Println(s1, s2, s3)

	// 4. 初始化赋值
	var s4 []int = make([]int, 0, 0)
	fmt.Println(s4)

	s5 := []int{1,2,3}
	fmt.Println(s5)

	// 5. 从数组切片
	arr := [5]int{1,2,3,4,5}
	var s6 []int
	s6 = arr[1:4]
	fmt.Println(s6)
}

2. 切片操作

操作 含义
s[n] 切片 s 中索引位置为 n 的项
s[:] 从切片 s 的索引位置 0 到 len(s)-1 处所获得的切片
s[low:] 从切片 s 的索引位置 low 到 len(s)-1 处所获得的切片
s[:high] 从切片 s 的索引位置 0 到 high 处所获得的切片,len=high
s[low:high] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low
s[low: high:max] 从切片 s 的索引位置 low 到 high 处所获得的切片,len=high-low, cap=max-low
len(s) 切片 s 的长度,总是<=cap()
cap(s) 切片 s 的容量,总是>=len(s)
package main

import "fmt"

func op01() {
	// 定义数组
	array := [...]int{1, 2, 3, 4, 5, 6, 7, 9, 0}

	// 切片
	fmt.Println(array[:])
	fmt.Println(array[1:5])
	fmt.Println(array[:6])
	fmt.Println(array[2:])
	fmt.Println(array[2])
}

func op02() {
	s1 := make([]int, 3, 5)
	fmt.Printf("s1: %v, len: %d, cap: %d", s1, len(s1), cap(s1))
}

func op03() {
	// 初始化一个数组
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}

	s1 := arr[2:5]
	fmt.Println(s1)

	// 可以向后扩展,默认是不扩展,不可以向前扩展
	s2 := s1[2:7]
	fmt.Println(s2)
}

func main() {
	op01()
	op02()
	op03()
}

3. append()函数

向 slice 尾部添加数据,返回新的 slice 对象

package main

import "fmt"

func main() {
	// 空切片
	var s001 []int

	s001 = append(s001, 1)
	s001 = append(s001, 3)
	s001 = append(s001, 6)
	fmt.Println(s001)

	// 初始化内存的切片
	s002 := make([]int, 5)
	s002 = append(s002, 5, 8, 9)
	fmt.Println(s002)

	// 初始化默认值的切片
	s003 := []int{1, 3, 6}
	s003 = append(s003, 4, 99, 2)
	fmt.Println(s003)
}
package main

import "fmt"

func main() {
	// 初始化一个数组
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8}

	// 初始化一个从数组切片的slice
	s1 := arr[2:]
	fmt.Println(arr)
	fmt.Println(s1)

	// 修改s1切片的值
	// view(视图)操作,会修改原数组的值
	s1[0] = 100
	fmt.Println(s1)
	fmt.Println(arr)
}

// 输出结果
// [0 1 2 3 4 5 6 7 8]
// [2 3 4 5 6 7 8]
// [100 3 4 5 6 7 8]
// [0 1 100 3 4 5 6 7 8]
package main

import "fmt"

func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
	s1 := arr[2:6]
	fmt.Println(s1)
	s2 := s1[3:5]
	fmt.Println(s2)

	// 映射到底层是覆盖操作
	s3 := append(s2, 10)
	fmt.Println(s3)
	fmt.Println(arr)
	fmt.Println()

	// 底层去自动扩容, 此时打印的是原数组
	s4 := append(s3, 11)
	fmt.Println(s4)
	fmt.Println(arr)

	s5 := append(s4, 12)
	fmt.Println(s5)
	fmt.Println(arr)
}
package main

import "fmt"

func main() {
	var a []int = []int{1, 2, 3}
	var b []int = []int{4, 5, 6}

	a = append(a, 7, 8)
	fmt.Println(a)

	// append无法直接添加一个切片,需要使用...将切片打散
	a = append(a, b...)
	fmt.Println(a)
}

4. copy()函数

在两个 slice 间复制数据,两个 slice 可指向同一底层数组

package main

import "fmt"

func main() {
	arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
	s1 := arr[8:] // [8 9 10 11 12 13 14]
	s2 := arr[:5] // [0 1 2 3 4]
	fmt.Println(s1, s2)

	// 从左侧开始覆盖
	copy(s1, s2)
	fmt.Println(s1, s2) // [0 1 2 3 4 13 14] [0 1 2 3 4]
	fmt.Println(arr)    // [0 1 2 3 4 5 6 7 0 1 2 3 4 13 14]
}

5. 切片扩容机制

用 make()创建切片,可以指定容量,当容量存储到上限,底层会自动扩容

package main

import "fmt"

func main() {
	var a []int = make([]int, 5, 10)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

	a[0] = 10
	a[1] = 20
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

	a = append(a, 30)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

	for i := 0; i <= 8; i++ {
		a = append(a, i)
		fmt.Printf("for a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

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

切片再切片

package main

import "fmt"

func main() {
	a := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	b := a[1:3]
	fmt.Printf("b=%v, len=%d, cap=%d\n", b, len(b), cap(b))

	// 切片再切片
	b = b[:cap(b)]
	fmt.Printf("b=%v, len=%d, cap=%d\n", b, len(b), cap(b))
}

空切片的扩容机制

package main

import "fmt"

func main() {
	var a []int
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))

	a = append(a, 10)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	a = append(a, 20)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	a = append(a, 30)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	a = append(a, 40)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	a = append(a, 50)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
	a = append(a, 60)
	fmt.Printf("a=%v, len=%d, cap=%d\n", a, len(a), cap(a))
}
posted @ 2020-03-17 13:11  ZhiChao&  阅读(282)  评论(0编辑  收藏  举报