V
Vel·ToolKit
简洁 · 高效 · 即开即用
ZH
第 6 章 / 共 20 章

数组与切片

固定数组、切片底层结构、make/append/copy

数组

数组长度是类型的一部分,[3]int 与 [4]int 是不同类型。传参时值拷贝,因此实际开发几乎不直接用数组。

package main

import "fmt"

func main() {
    var a [3]int           // [0 0 0]
    b := [3]int{1, 2, 3}
    c := [...]int{1, 2, 3} // 编译器推断长度
    fmt.Println(a, b, c, len(c))
}

切片

切片是对底层数组的引用,含指针、长度、容量。可以动态增长,是 Go 最常用的集合类型。

package main

import "fmt"

func main() {
    s := []int{1, 2, 3} // 字面量
    s = append(s, 4, 5)

    s2 := make([]int, 3, 10) // len=3, cap=10

    fmt.Println(s, len(s), cap(s))
    fmt.Println(s[1:3]) // 子切片 [2 3]
    fmt.Println(s2)
}

append 扩容

当 cap 不够时,append 会分配新底层数组并复制。返回值必须重新赋给原切片。

package main

import "fmt"

func main() {
    s := []int{1, 2, 3}
    s = append(s, 4) // 必须赋值回去
    fmt.Println(s, len(s), cap(s))
}

copy 与共享底层数组

子切片共享底层数组,修改会互相影响。用 copy 或 append 到 nil 切片可创建独立副本。

package main

import "fmt"

func main() {
    src := []int{1, 2, 3}
    dst := make([]int, len(src))
    copy(dst, src)

    // 简洁写法
    dst2 := append([]int(nil), src...)

    src[0] = 99
    fmt.Println(src, dst, dst2)
}