1.5 golang 复合数据类型

3 阅读2分钟

1.5 复合数据类型

数组(Array)

数组是固定长度的同类型元素序列。

package main

import "fmt"

func main() {
    var scores [5]int
    scores[0] = 90
    scores[1] = 85
    fmt.Println(scores) // [90 85 0 0 0]

    colors := [3]string{"红", "绿", "蓝"}
    primes := [...]int{2, 3, 5, 7, 11} // 编译器计算长度
    fmt.Println(colors, primes)
}

⚠️ 数组在 Go 中较少使用,实际开发中更常用切片

切片(Slice)⭐

切片是动态长度的引用类型,底层是对数组的引用。

创建切片

func main() {
    s1 := []int{10, 20, 30}           // 字面量
    s2 := make([]int, 3, 5)           // make(类型, 长度, 容量)
    arr := [5]int{1, 2, 3, 4, 5}
    s3 := arr[1:4]                    // 从数组截取 [2,3,4]

    fmt.Println(s1, s2, s3)
    fmt.Println(len(s2), cap(s2))     // 3, 5
}

append 与切片操作

func main() {
    s := []int{1, 2, 3}
    s = append(s, 4, 5)               // 追加元素
    extra := []int{6, 7}
    s = append(s, extra...)            // 追加切片

    // 切片截取
    fmt.Println(s[2:5])  // [3 4 5]
    fmt.Println(s[:3])   // [1 2 3]
    fmt.Println(s[4:])   // [5 6 7]

    // 删除索引为2的元素
    s = append(s[:2], s[3:]...)

    // 复制切片
    dst := make([]int, len(s))
    copy(dst, s)
}

底层原理

切片包含三个字段:指针(指向底层数组)、长度(len)、容量(cap)。超过容量时 append 会自动扩容(通常翻倍)。切片是引用类型,修改会影响底层数组。

Map(映射)

func main() {
    // 创建
    ages := map[string]int{
        "Alice": 25,
        "Bob":   30,
    }

    // 增改
    ages["Carol"] = 28
    ages["Alice"] = 26

    // 查(comma-ok 模式)
    val, ok := ages["Dave"]
    if !ok {
        fmt.Println("Dave 不存在")
    }
    _ = val

    // 删
    delete(ages, "Bob")

    // 遍历
    for name, age := range ages {
        fmt.Printf("%s: %d\n", name, age)
    }
}

⚠️ var m map[string]int 是 nil map,写入会 panic,必须先 make

结构体(Struct)

type Person struct {
    Name  string
    Age   int
    Email string
}

type Address struct {
    City, Street string
}

type Employee struct {
    Person         // 匿名嵌入:可以直接访问 Name、Age
    Address        // 匿名嵌入
    Department string
}

func main() {
    p := Person{Name: "Alice", Age: 25, Email: "a@b.com"}
    fmt.Println(p.Name)

    emp := Employee{
        Person:     Person{Name: "Bob", Age: 30},
        Address:    Address{City: "北京", Street: "中关村"},
        Department: "工程部",
    }
    fmt.Println(emp.Name)   // 直接访问嵌入字段
    fmt.Println(emp.City)   // 直接访问嵌入字段

    // 结构体指针(Go 自动解引用)
    pp := &p
    fmt.Println(pp.Name)    // 等价于 (*pp).Name

    // 结构体标签(用于 JSON 等)
    // type User struct {
    //     Name string `json:"name"`
    // }

    // 结构体比较
    p2 := Person{Name: "Alice", Age: 25, Email: "a@b.com"}
    fmt.Println(p == p2) // true
}

小结

类型特点使用频率
数组固定长度,值类型
切片动态长度,引用类型⭐⭐⭐
Map键值对,无序,引用类型⭐⭐⭐
结构体自定义类型,字段集合⭐⭐⭐