查看: 64|回复: 0

上篇Go学习笔记-续

[复制链接]

45

贡献

36

主题

164

积分

版主

积分
164
QQ
发表于 2026-7-4 22:16:40 | 显示全部楼层 |阅读模式
我们上节末尾将要讲向切片里添加元素。

使用append([SliceName], element1, element2,...)的方式可以制作一个名叫SliceName的切片添加完element1, element2, ...之后的切片。
示例:
  1. package main

  2. import "fmt"

  3. func main() {
  4.         var s []int
  5.         printSlice(s)

  6.         // append works on nil slices.
  7.         s = append(s, 0)
  8.         printSlice(s)

  9.         // The slice grows as needed.
  10.         s = append(s, 1)
  11.         printSlice(s)

  12.         // We can add more than one element at a time.
  13.         s = append(s, 2, 3, 4)
  14.         printSlice(s)
  15. }

  16. func printSlice(s []int) {
  17.         fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
  18. }
复制代码
输出:
  1. len=0 cap=0 []
  2. len=1 cap=1 [0]
  3. len=2 cap=2 [0 1]
  4. len=5 cap=6 [0 1 2 3 4]
复制代码
当然这是使用内置方案操作切片的方式,我们接下来讲一种更为原理性的方式(稍微复杂一点,如果不是需要深入了解Go的同志们可以直接跳到文章末尾)。
想要扩展切片很显然可以使用make函数做一个新的切片,它的cap比原来的切片大,然后将原来的切片的所有值全都复制到新做的切片里(这个新切片的位置还有空余!),然后再将新切片的值赋值给原来的切片。
  1. t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
  2. for i := range s {
  3.         t[i] = s[i]
  4. }
  5. s = t
复制代码

当然我们没有必要使用循环,因为Go有内置的copy方法,能将数组里面的值一一对应复制:
Go语言内置的copy函数用于将源切片中的元素复制到目标切片。它的基本形式是 copy(dst, src),其中dst(目标)和src(源头)都是切片类型。返回值是实际复制的元素个数,这个数值等于dst和src长度中较小的那个。

使用时需要注意几点:第一,copy不会自动扩容目标切片,所以如果目标切片长度小于源切片,只会复制目标长度那么多元素,多余部分被丢弃;如果目标长度大于源,则只复制源的所有元素,目标剩余位置保持不变。第二,copy支持源和目标为同一切片的不同重叠区域,复制行为是安全的,会按预期处理重叠部分。第三,copy处理的是元素值复制,对于指针或引用类型,复制的是指针或引用本身,不是深层拷贝。第四,copy也可以用于将字符串复制到字节切片,因为字符串可以视为只读的字节源,但目标必须是[]byte。

实际使用中,常见场景包括:合并切片时先make足够大的目标切片然后copy;删除切片中间元素时用copy移动后续元素;或者将数据从临时缓冲区复制到固定大小数组的切片视图等。总之,copy是切片操作中高效且常用的基础函数,理解其长度限制和返回值有助于避免数据丢失或意外截断。

假设 a := []int{1, 2},b := []int{9, 9, 9}。copy(b, a) 会把 [1,2] 复制到 b 的开头,结果是 b = [1, 2, 9]。如果调换成 copy(a, b),因为 a 长度是2,只会把 b 的前两个元素 [9,9] 复制到 a 中,结果是 a = [9, 9],而 b 保持不变。
简化为:
  1. t := make([]byte, len(s), (cap(s)+1)*2)
  2. copy(t, s)
  3. s = t
复制代码

本文介绍得比较浅薄,强烈建议建议读者移步Go Slices: usage and internals - The Go Programming Language来深入理解slices的内涵。


Hi~ o(* ̄▽ ̄*)ブ I Love U ~
查看帮助

相关侵权、举报、投诉及建议等,请按帮助内指引进行反馈

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部