ZetCode

Golang append 函数

最后修改时间 2025 年 5 月 8 日

本教程将解释如何在 Go 中使用内置的 append 函数。我们将通过实际的动态切片操作示例来涵盖切片基础知识。

append 函数用于向 Go 中的切片添加元素。它会在需要时处理底层数组的自动重定义大小。该函数返回一个包含所有原始元素以及新元素的新切片。

在 Go 中,append 对于处理动态集合至关重要。当切片超出其当前容量时,它可以有效地管理内存分配和复制。

基本 append 示例

append 最简单的用法是将元素添加到切片中。本示例演示了基本的切片追加。
注意: 始终将 append 的返回值赋给一个变量。

basic_append.go
package main

import "fmt"

func main() {
    var nums []int
    
    // Append single elements
    nums = append(nums, 1)
    nums = append(nums, 2)
    nums = append(nums, 3)
    
    fmt.Println(nums) // [1 2 3]
    
    // Append multiple elements
    nums = append(nums, 4, 5, 6)
    fmt.Println(nums) // [1 2 3 4 5 6]
}

该示例展示了单元素和多元素追加。每个 append 操作都会返回一个必须重新赋给变量的新切片。

向具有容量的切片追加

当切片具有足够的容量时,append 会重用底层数组。本示例演示了 append 操作期间的容量行为。

capacity_append.go
package main

import "fmt"

func main() {
    // Create slice with length 3 and capacity 5
    nums := make([]int, 3, 5)
    nums[0], nums[1], nums[2] = 1, 2, 3
    
    fmt.Printf("Before append: len=%d cap=%d %v\n", 
        len(nums), cap(nums), nums)
    
    // Append within capacity
    nums = append(nums, 4)
    fmt.Printf("After first append: len=%d cap=%d %v\n", 
        len(nums), cap(nums), nums)
    
    // Append beyond capacity
    nums = append(nums, 5, 6)
    fmt.Printf("After second append: len=%d cap=%d %v\n", 
        len(nums), cap(nums), nums)
}

由于容量足够,第一次 append 没有分配新内存。第二次 append 因为超过了容量而触发了新的分配。

将一个切片追加到另一个切片

我们可以使用展开运算符将一个切片的所有元素追加到另一个切片。本示例展示了如何高效地组合切片。

slice_append.go
package main

import "fmt"

func main() {
    fruits := []string{"apple", "banana"}
    moreFruits := []string{"orange", "grape", "kiwi"}
    
    // Append all elements of moreFruits to fruits
    fruits = append(fruits, moreFruits...)
    
    fmt.Println(fruits) // [apple banana orange grape kiwi]
    
    // Create new slice by combining
    allFruits := append([]string{}, fruits...)
    allFruits = append(allFruits, "melon")
    
    fmt.Println(allFruits) // [apple banana orange grape kiwi melon]
}

... 运算符将切片展开为单独的元素。这种模式对于在没有嵌套切片结构的情况下组合切片很有用。

向 nil 切片追加

Append 可以与 nil 切片一起使用,并在需要时自动创建新切片。本示例演示了 append 对 nil 切片行为。

nil_append.go
package main

import "fmt"

func main() {
    var nilSlice []int
    
    fmt.Printf("nilSlice: len=%d cap=%d %v\n", 
        len(nilSlice), cap(nilSlice), nilSlice)
    
    // Append to nil slice
    nilSlice = append(nilSlice, 10)
    fmt.Printf("After append: len=%d cap=%d %v\n", 
        len(nilSlice), cap(nilSlice), nilSlice)
    
    // Multiple appends
    nilSlice = append(nilSlice, 20, 30, 40)
    fmt.Printf("Final state: len=%d cap=%d %v\n", 
        len(nilSlice), cap(nilSlice), nilSlice)
}

当与 append 一起使用时,nil 切片表现得像一个空切片。在第一次向 nil 切片追加时,Go 会自动处理初始分配。

使用接口追加不同类型

我们可以通过使用空接口将不同类型追加到切片中。本示例演示了带有 append 的异构集合。

interface_append.go
package main

import "fmt"

func main() {
    var items []interface{}
    
    items = append(items, 42)
    items = append(items, "hello")
    items = append(items, 3.14)
    items = append(items, true)
    
    for i, item := range items {
        fmt.Printf("Item %d: %v (%T)\n", i, item, item)
    }
}

空接口 interface{} 允许存储任何类型。尽管元素位于同一个切片中,但每个元素都保留其原始类型信息。

来源

Go 语言规范

本教程通过动态切片操作和增长模式的实际示例,涵盖了 Go 中的 append 函数。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面有十多年的经验。

列出所有 Golang 教程