欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > Golang学习笔记_14——切片

Golang学习笔记_14——切片

2024/12/21 10:14:39 来源:https://blog.csdn.net/LuckyLay/article/details/144559374  浏览:    关键词:Golang学习笔记_14——切片

Golang学习笔记_11——指针
Golang学习笔记_12——结构体
Golang学习笔记_13——数组


文章目录

    • 切片
      • 1. 定义
      • 2. 创建
      • 3. 基本操作
      • 4. 动态性
      • 5. 子切片
      • 6. 数组和切片
      • 7. 注意
      • 8. 高级用法
    • 源码


切片

Go语言中的切片(slice)是一种非常强大且灵活的数据结构,它基于数组,但提供了更加动态和方便的接口。

1. 定义

切片是对数组的抽象和封装,它包含三个关键部分:

  1. 指向数组的指针:切片存储了数组的首地址,指向数组中的某个元素。
  2. 切片的长度(len):切片中元素的数量。
  3. 切片的容量(cap):从切片的首元素到数组末尾的元素数量,表示在不需要重新分配底层数组的情况下,切片可以增长的最大长度。

2. 创建

func sliceDemo1() {// 通过字面量创建s1 := []int{1, 2, 3}// 通过make函数创建// 创建一个长度为3,容量为5的切片s2 := make([]int, 3, 5)// 基于数组创建arr := [5]int{1, 2, 3, 4, 5}s3 := arr[1:4]fmt.Println(s1, s2, s3)}

3. 基本操作

func sliceDemo2() {// 访问和修改元素s1 := []int{1, 2, 3}fmt.Println(s1[0]) // 输出1s1[0] = 10fmt.Println(s1)// 切片多重赋值a, b, c := s1[0], s1[1], s1[2]fmt.Println(a, b, c)// 切片的长度和容量s := []int{1, 2, 3, 4, 5}fmt.Println(len(s)) // 输出5fmt.Println(cap(s)) // 输出5,因为是基于字面量创建的,默认容量等于长度}

测试方法

func Test_sliceDemo2(t *testing.T) {sliceDemo2()
}

输出结果

=== RUN   Test_sliceDemo2
1
[10 2 3]
10 2 3
5
5
--- PASS: Test_sliceDemo2 (0.00s)
PASS

4. 动态性

func sliceDemo3() {s := []int{1, 2, 3}s = append(s, 4, 5) // s现在是[1, 2, 3, 4, 5]fmt.Println(s)
}

测试方法

func Test_sliceDemo3(t *testing.T) {sliceDemo3()
}

输出结果

=== RUN   Test_sliceDemo3
[1 2 3 4 5]
--- PASS: Test_sliceDemo3 (0.00s)
PASS

当向切片中追加元素时,如果切片的容量不足,Go会自动分配一个更大的底层数组,并将原有元素复制到新的数组中。新数组的容量通常是原容量的两倍。

5. 子切片

func sliceDemo4() {s := []int{1, 2, 3, 4, 5}subSlice := s[1:4] // subSlice是[2, 3, 4]fmt.Println(subSlice)
}

测试方法

func Test_sliceDemo4(t *testing.T) {sliceDemo4()
}

输出结果

=== RUN   Test_sliceDemo4
[2 3 4]
--- PASS: Test_sliceDemo4 (0.00s)
PASS

6. 数组和切片

  1. 长度:数组的长度是固定的,而切片的长度是动态的。
  2. 内存分配:数组直接存储数据,切片是对数组的抽象,存储的是指向数组的指针、长度和容量。
  3. 效率:数组在栈上分配内存,效率较高,但长度固定;切片在堆上分配内存,且可以动态扩展,但有一定性能开销。

7. 注意

  1. 共享底层数组:多个切片可以共享同一个底层数组,修改一个切片可能影响其他切片。

  2. 越界访问:访问切片时,如果索引超出范围,会导致运行时错误(panic)。

  3. nil切片:未初始化的切片值为nil,长度为0,容量为0。

  4. 在进行切片时,你可以利用它的默认行为来忽略上下界。切片下界的默认值为 0,上界则是该切片的长度。

    var a [10]inta[0:10]
    a[:10]
    a[0:]
    a[:]
    // 上述表达是等价的
    

8. 高级用法

func sliceDemo5() {// 切片拷贝s := []int{1, 2, 3}var s_dst = make([]int, len(s))copy(s, s_dst)fmt.Println(s_dst)// 切片分割s1 := []int{1, 2, 3}s2 := []int{4, 5, 6}s3 := append(s1, s2...) // s3是[1, 2, 3, 4, 5, 6]fmt.Println(s3)
}

测试方法

func Test_sliceDemo5(t *testing.T) {sliceDemo5()
}

输出结果

=== RUN   Test_sliceDemo5
[0 0 0]
[1 2 3 4 5 6]
--- PASS: Test_sliceDemo5 (0.00s)
PASS

源码

// slice_demo.go 文件
package _4_slice_demoimport "fmt"func sliceDemo1() {// 通过字面量创建s1 := []int{1, 2, 3}// 通过make函数创建// 创建一个长度为3,容量为5的切片s2 := make([]int, 3, 5)// 基于数组创建arr := [5]int{1, 2, 3, 4, 5}s3 := arr[1:4]fmt.Println(s1, s2, s3)}func sliceDemo2() {// 访问和修改元素s1 := []int{1, 2, 3}fmt.Println(s1[0]) // 输出1s1[0] = 10fmt.Println(s1)// 切片多重赋值a, b, c := s1[0], s1[1], s1[2]fmt.Println(a, b, c)// 切片的长度和容量s := []int{1, 2, 3, 4, 5}fmt.Println(len(s)) // 输出5fmt.Println(cap(s)) // 输出5,因为是基于字面量创建的,默认容量等于长度}func sliceDemo3() {s := []int{1, 2, 3}s = append(s, 4, 5) // s现在是[1, 2, 3, 4, 5]fmt.Println(s)
}func sliceDemo4() {s := []int{1, 2, 3, 4, 5}subSlice := s[1:4] // subSlice是[2, 3, 4]fmt.Println(subSlice)
}func sliceDemo5() {// 切片拷贝s := []int{1, 2, 3}var s_dst = make([]int, len(s))copy(s, s_dst)fmt.Println(s_dst)// 切片分割s1 := []int{1, 2, 3}s2 := []int{4, 5, 6}s3 := append(s1, s2...) // s3是[1, 2, 3, 4, 5, 6]fmt.Println(s3)
}
// 14_slice_demo_test.go 文件
package _4_slice_demoimport "testing"func Test_sliceDemo2(t *testing.T) {sliceDemo2()
}func Test_sliceDemo3(t *testing.T) {sliceDemo3()
}func Test_sliceDemo4(t *testing.T) {sliceDemo4()
}func Test_sliceDemo5(t *testing.T) {sliceDemo5()
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com