Skip to content

切片

  • 切片:是动态数组,长度是不固定的。

声明切片

  • 格式1:var slice []type
  • 格式2:var var slice []type = make([]type, len, cap)
go
// 方式1
var slice []string
slice = append(slice, "I'm")
slice = append(slice, "like", "cat", "and", "dog")

// 方式2
slice2 := []string{"I'm", "like", "cat", "and", "dog"}

// 方式3
slice3 := make([]string, 0)
slice3 = append(slice3, slice...)

// 打印结果
fmt.Printf("%+v len:%d cap:%d \n", slice, len(slice), cap(slice))
fmt.Printf("%+v len:%d cap:%d \n", slice2, len(slice2), cap(slice2))
fmt.Printf("%+v len:%d cap:%d \n", slice3, len(slice3), cap(slice3))

输出结果

[I'm like cat and dog] len:5 cap:8

[I'm like cat and dog] len:5 cap:8

[I'm like cat and dog] len:5 cap:8

元素操作

创建切片

go
slice := []string{"I'm"}
fmt.Printf("%+v len:%d cap:%d \n", slice, len(slice), cap(slice))

输出结果

[I'm] len:1 cap:1

追加元素

go
slice = append(slice, "like")
slice = append(slice, "cat")
// 追加多个元素
slice = append(slice, "and", "dog")
fmt.Printf("%+v len:%d cap:%d \n", slice, len(slice), cap(slice))

输出结果

[I'm like cat and dog] len:5 cap:8

编辑元素

go
slice[4] = "monkey"
fmt.Printf("%+v len:%d cap:%d \n", slice, len(slice), cap(slice))

输出结果

[I'm like cat and monkey] len:5 cap:8

截取元素

go
fmt.Println("取第一个元素", slice[0])

// 可以简写为arr[:2],表示从索引0开始取,直到索引2(不包含索引2)
fmt.Println("取下标0-1的元素", slice[0:2])

// 表示从索引3开始取,直到数组末尾
fmt.Println("取下标3之后的元素", slice[3:])

输出结果

取第一个元素 I'm

取下标0-1的元素 [I'm like]

取下标3之后的元素 [and monkey]

删除元素

go
// 删除索引为1的元素
// 1. 先取索引0的元素作为一个新的数组,
// 2. 再取索引2之后的元素索引元素追加到新的数组中,达到删除效果
arr = append(slice[:1], slice[2:]...)
fmt.Println(arr)

输出结果

[I'm cat and monkey] len:4 cap:8

查询元素

  • go 没有直接方法查询数组是否存在某个元素
  • 可以通过遍历数组, 比较每个元素是否等于目标元素, 来判断数组是否存在某个元素.
go
// 定义一个数组变量
sli1 := []string{"I'm", "like", "cat", "and", "monkey"}
str1 := "cat"

// 方式1
for _,value := range sli1{
	if value == str1{
		fmt.Println("数组存在元素", str1)
	}
}

// 方式2 基于 slices 包的 Index 方法
if slices.Contains(sli1, str1) {
	fmt.Println("数组存在元素", str1)
}

// 方式3 基于 sort 包的 Search方法
if sort.SearchStrings(sli1, str1) >-1 {
	fmt.Println("数组存在元素", str1)
}

数组处理集成

go
package types

// 定义 可以比较的泛型 结构体
type Slice[T comparable] struct {
	data []T
}

// 初始化 Slice
func NewSlice[T comparable](s []T) *Slice[T] {
	return &Slice[T]{data: s}
}

// 获取切片长度
func (s *Slice[T]) Len() int {
	return len(s.data)
}

// 转为 map
func (s *Slice[T]) toMap() map[T]struct{} {
	m := make(map[T]struct{}, len(s.data))
	for _, v := range s.data {
		m[v] = struct{}{}
	}
	return m
}

// 判断是否包含某个元素
func (s *Slice[T]) Contains(i T) bool {
	m := s.toMap()
	if _, ok := m[i]; ok {
		return true
	}
	return false
}

// 查找某个元素的索引,未找到索引为-1
func (s *Slice[T]) FindIndex(i T) int {
	for index, v := range s.data {
		if v == i {
			return index
		}
	}
	return -1
}

空切片

  • 空切片是指长度为0的切片,它的容量也为0。
go
var slice []string
fmt.Printf("%+v len:%d cap:%d \n", slice, len(slice), cap(slice))
// 空切片是 nil
if slice == nil {
    fmt.Println("nil")
} else {
    fmt.Println("not nil")
}

切片转字符串

go
// 把切片按照指定的分隔符连接成一个字符串
str := strings.Join(slice, ",")
fmt.Println(str)

输出结果

I'm,cat,and,monkey

字符串转切片

go
// 把切片按照指定的分隔符连接成一个字符串
slice := strings.Split(str, ",")
fmt.Printf("%+v len:%d cap:%d \n", slice2, len(slice), cap(slice))

输出结果

[I'm cat and monkey] len:4 cap:8