02.Slice 切片

切片(Slice)是 Go 语言中比数组更为灵活和强大的数据结构。切片本质上是对数组的一个视图,可以动态调整大小。下面详细介绍切片的定义、初始化、操作和使用注意事项。

切片的定义与初始化

切片的定义语法为:[]T,其中 T 表示切片元素的类型。切片的初始化可以通过数组字面量、内置函数 make 或从现有数组或切片中创建。

示例

package main

import "fmt"

func main() {
    // 使用数组字面量初始化切片
    slice1 := []int{1, 2, 3, 4, 5}
    fmt.Println(slice1) // 输出:[1 2 3 4 5]

    // 使用内置函数 make 初始化切片
    slice2 := make([]int, 5)
    fmt.Println(slice2) // 输出:[0 0 0 0 0]

    // 从现有数组或切片中创建切片
    arr := [5]int{10, 20, 30, 40, 50}
    slice3 := arr[1:4] // 包含索引 1 到 3 的元素,不包括 4
    fmt.Println(slice3) // 输出:[20 30 40]
}

切片的基本操作

访问与修改元素

切片的元素访问和修改与数组类似,通过索引进行。

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println(slice[0]) // 输出:1

    slice[1] = 20
    fmt.Println(slice) // 输出:[1 20 3 4 5]
}

 

获取切片长度和容量

切片的长度通过 len 函数获取,容量通过 cap 函数获取。

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println("Length:", len(slice)) // 输出:Length: 5
    fmt.Println("Capacity:", cap(slice)) // 输出:Capacity: 5
}

 

切片的动态增长

切片的长度可以通过内置函数 append 动态增加。

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3}
    slice = append(slice, 4, 5)
    fmt.Println(slice) // 输出:[1 2 3 4 5]
}

 

切片的遍历

使用 for 循环或 range 关键字遍历切片。

package main

import "fmt"

func main() {
    slice := []int{1, 2, 3, 4, 5}

    // 使用传统的 for 循环遍历切片
    for i := 0; i < len(slice); i++ {
        fmt.Println(slice[i])
    }

    // 使用 range 关键字遍历切片
    for index, value := range slice {
        fmt.Printf("Index: %d, Value: %d\n", index, value)
    }
}

 

多维切片

Go 语言支持多维切片。

package main

import "fmt"

func main() {
    // 定义一个二维切片
    var matrix [][]int

    // 初始化二维切片
    matrix = [][]int{
        {1, 2, 3},
        {4, 5, 6},
    }
    
    fmt.Println(matrix) // 输出:[[1 2 3] [4 5 6]]

    // 访问二维切片元素
    fmt.Println(matrix[0][1]) // 输出:2

    // 遍历二维切片
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[i]); j++ {
            fmt.Printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j])
        }
    }
}

 

使用切片应注意的点

  slice 可以向后扩展,不可以向前扩展

  s[i] 不可以超越 len(s),向后扩展不可以超越底层数组cap(s)

 

  1. 切片的零值:切片的零值是 nil,一个 nil 切片的长度和容量都是 0。

    var slice []int
    fmt.Println(slice == nil) // 输出:true
    fmt.Println(len(slice)) // 输出:0
    fmt.Println(cap(slice)) // 输出:0
  2. 共享底层数组:切片是对底层数组的引用,多个切片可以共享同一个底层数组。对一个切片的修改可能影响共享相同底层数组的其他切片。

    arr := [5]int{1, 2, 3, 4, 5}
    slice1 := arr[:]
    slice2 := arr[2:]
    slice2[0] = 100
    fmt.Println(slice1) // 输出:[1 2 100 4 5]
    fmt.Println(slice2) // 输出:[100 4 5]
  3. 使用 append 时的容量增长:如果切片的容量不足以容纳新的元素,append 操作会创建一个新的底层数组,将旧数组的内容复制过去。

    slice := []int{1, 2, 3}
    fmt.Printf("Before append: len = %d, cap = %d\n", len(slice), cap(slice))
    slice = append(slice, 4, 5)
    fmt.Printf("After append: len = %d, cap = %d\n", len(slice), cap(slice))

切片的切片:可以对切片再进行切片操作,但新切片仍然引用相同的底层数组。

slice := []int{1, 2, 3, 4, 5}
subSlice := slice[1:4]
fmt.Println(subSlice) // 输出:[2 3 4]

切片(Slice)是 Go 语言中比数组更为灵活和强大的数据结构。切片本质上是对数组的一个视图,可以动态调整大小。下面详细介绍切片的定义、初始化、操作和使用注意事项。

综合示例

下面的代码展示了切片的各种操作,包括定义、初始化、访问、修改、遍历、动态增长和多维切片的使用。

package main

import "fmt"

func main() {
    // 定义和初始化切片
    slice := []int{1, 2, 3, 4, 5}
    fmt.Println("Initial slice:", slice)

    // 访问和修改元素
    slice[2] = 100
    fmt.Println("Modified slice:", slice)

    // 获取切片长度和容量
    fmt.Println("Length:", len(slice))
    fmt.Println("Capacity:", cap(slice))

    // 动态增长切片
    slice = append(slice, 6, 7)
    fmt.Println("Appended slice:", slice)

    // 遍历切片
    fmt.Println("Slice elements:")
    for i, v := range slice {
        fmt.Printf("Index: %d, Value: %d\n", i, v)
    }

    // 多维切片
    matrix := [][]int{
        {1, 2, 3},
        {4, 5, 6},
    }
    fmt.Println("2D Slice:", matrix)
    
    // 遍历多维切片
    for i := 0; i < len(matrix); i++ {
        for j := 0; j < len(matrix[i]); j++ {
            fmt.Printf("matrix[%d][%d] = %d\n", i, j, matrix[i][j])
        }
    }
}
posted @ 2024-07-08 17:03  JJJhr  阅读(18)  评论(0编辑  收藏  举报