0Pricing
Go Academy · 课时

切片:动态列表

make、append、copy、len 与 cap

切片:动态列表 是 CoddyKit 上的免费 Go Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Go Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Go Academy 课程共包含 4 节课。

什么是切片?

切片是对底层数组的动态大小视图。它包含三个组成部分:指向数组的指针、长度和容量。

  • 切片是引用类型——多个切片可以共享同一个底层数组
  • Go 中大多数类似列表的操作都使用切片,而不是数组

切片字面量与 make

使用字面量或 make 创建切片:

package main
import "fmt"

func main() {
    nums := []int{1, 2, 3, 4, 5}      // literal
    strs := make([]string, 3)          // len=3, cap=3, zero values
    buf  := make([]byte, 0, 64)        // len=0, cap=64
    fmt.Println(nums, strs, len(buf), cap(buf))
}

len 与 cap

len 返回切片当前包含的元素数量。cap 返回从切片起始指针开始计算的底层数组容量。

package main
import "fmt"

func main() {
    s := make([]int, 3, 8)
    fmt.Println(len(s)) // 3
    fmt.Println(cap(s)) // 8
}

append:增长切片

append 会向切片添加元素;当容量不足时,它会分配新的底层数组:

package main
import "fmt"

func main() {
    s := []int{1, 2, 3}
    s = append(s, 4, 5)
    s = append(s, []int{6, 7, 8}...)
    fmt.Println(s) // [1 2 3 4 5 6 7 8]
}

切分切片

使用 [low:high] 语法创建子切片(子切片会共享底层数组):

package main
import "fmt"

func main() {
    a := []int{0, 1, 2, 3, 4, 5}
    b := a[1:4]   // [1 2 3]
    c := a[:3]    // [0 1 2]
    d := a[3:]    // [3 4 5]
    fmt.Println(b, c, d)
}

copy:创建独立切片

copy 会在切片之间复制元素,并返回复制的元素数量。目标切片和源切片不共享内存:

package main
import "fmt"

func main() {
    src := []int{1, 2, 3}
    dst := make([]int, len(src))
    n := copy(dst, src)
    dst[0] = 99
    fmt.Println(src, dst, n) // [1 2 3] [99 2 3] 3
}

nil 切片与空切片

nil 切片没有底层数组。空切片有底层数组,但长度为 0。两者的 len == 0:

package main
import "fmt"

func main() {
    var nilSlice []int
    emptySlice  := []int{}
    fmt.Println(nilSlice  == nil) // true
    fmt.Println(emptySlice == nil) // false
    fmt.Println(len(nilSlice), len(emptySlice)) // 0 0
    nilSlice = append(nilSlice, 1) // safe!
}

删除元素

Go 没有用于切片的内置删除函数。惯用做法是使用 append:

package main
import "fmt"

func main() {
    s := []int{1, 2, 3, 4, 5}
    i := 2 // delete index 2
    s = append(s[:i], s[i+1:]...)
    fmt.Println(s) // [1 2 4 5]
}

插入元素

通过组合使用 append 和切片操作,在位置 i 处插入元素:

package main
import "fmt"

func main() {
    s := []int{1, 2, 4, 5}
    i := 2
    s = append(s[:i+1], s[i:]...)
    s[i] = 3
    fmt.Println(s) // [1 2 3 4 5]
}

切片陷阱:共享底层数组

子切片会共享底层数组——在重新分配发生之前,修改一个切片会影响另一个切片:

package main
import "fmt"

func main() {
    a := []int{1, 2, 3, 4}
    b := a[:2]   // shares backing array
    b[0] = 99
    fmt.Println(a) // [99 2 3 4] — a is changed!
}

快速检查

append 会返回什么?

回顾:切片

要点:

  • 切片 = 指针 + len + cap;切片封装了数组
  • 使用 make 预先分配容量
  • 始终为 append 的结果赋值
  • copy 会创建相互独立的切片
  • 请注意子切片共享底层数组的情况

练习提示

请使用 make 创建一个包含 5 个整数的切片,追加另外三个值,然后将其复制到新切片中,并修改副本且不影响原切片。请打印两个切片。

常见问题解答

「切片:动态列表」课时是免费的吗?

是的 — 「切片:动态列表」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Go Academy 课程的其余内容,请升级到 CoddyKit PRO。 Go Academy 课程共包含 4 节课。

「切片:动态列表」这节课中我会学到什么?

make、append、copy、len 与 cap 你通过在浏览器中直接运行的动手代码来练习 Go Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Go Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Go Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「切片:动态列表」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Go Academy 课中编写并运行代码吗?

能。每节 Go Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 数组:定长集合
  2. 切片:动态列表
  3. 映射:键值存储
  4. 使用 range 遍历集合
← 返回 Go Academy