Skip to content

array 与 slice

Phase 01 — Go Fundamentals · 知识点 07 · 08


1. 学习目标

  • 理解 array 固定长度、slice 动态长度
  • 掌握 slice 的创建、追加、切片操作
  • 理解 slice 底层是引用类型
  • 知道何时用 array(很少)vs slice(几乎总是)

2. 为什么需要

后端要处理一组数据:多个 AGV 坐标、一批传感器读数、设备 ID 列表。Go 用 array 和 slice 表示同类型元素集合,但日常开发 99% 用 slice


3. 核心概念

array — 固定长度

go
var coords [3]float64 = [3]float64{10.0, 20.0, 30.0}
// [3]float64 和 [5]float64 是不同类型!

slice — 动态长度

go
ids := []string{"AGV-001", "AGV-002"}
ids = append(ids, "AGV-003")

sub := ids[0:2]  // 切片 [start:end),左闭右开
操作说明
len(s)元素个数
cap(s)底层数组容量
append(s, x)追加元素,可能触发扩容
s[low:high]切片,共享底层数组

4. 基础语法

go
package main

import "fmt"

func main() {
    // 创建 slice
    speeds := make([]float64, 0, 10) // len=0, cap=10
    speeds = append(speeds, 1.2, 0.8, 1.5)

    // 遍历
    for i, v := range speeds {
        fmt.Printf("[%d] %.1f m/s\n", i, v)
    }

    // 只遍历值
    for _, v := range speeds {
        fmt.Println(v)
    }
}

5. 代码解析

  • make([]T, len, cap) 预分配,减少 append 扩容次数
  • append 返回新 slice(可能指向新底层数组)
  • 切片 sub := s[1:3]s 共享底层数组,修改 sub 可能影响 s

6. JavaScript / TypeScript 对比

Go sliceJS Array
同类型元素可混合类型
值语义+引用底层引用对象
[start:end) 左闭右开slice(start, end) 类似
无 map/filter 链式有丰富的数组方法

slice 只能类比 JS Array,底层机制并不相同。


7. 常见错误

  1. 对 nil slice append → 合法,会自动分配
  2. 切片共享底层导致意外修改 → 用 copy 复制
  3. 混淆 array 和 slice 类型[3]int[]int
  4. range 循环中修改 slice 长度 → 行为需小心

8. 实际应用

go
// AGV 路径点
path := []struct{ X, Y float64 }{
    {10, 5}, {20, 8}, {30, 12},
}

// 过滤超速 AGV
var overspeed []string
for _, agv := range agvs {
    if agv.Speed > maxSpeed {
        overspeed = append(overspeed, agv.ID)
    }
}

Three.js 前端接收的坐标数组,Go 后端用 []float64[]Position slice 组装 JSON。


9. 深入理解

slice 结构:pointer + len + cap。扩容策略通常翻倍,大数据量时用 make 预分配 cap 提升性能。


10. 练习

  • L1:创建、append、遍历 slice
  • L2:切片操作与 len/cap
  • L3:copy 避免共享底层
  • L4:管理 AGV 路径点 slice

11. 学习检查

  • [ ] array 与 slice 类型区别?
  • [ ] append 返回值为何要接收?
  • [ ] [start:end) 边界规则?

12. 下一步

map:键值对存储设备状态


学习导航

上一篇:Variables and Types · 对应练习 · 下一篇:map