// ✅ 深拷贝 — 逐行 copy deep := make([][]int, len(src)) for i := range src { deep[i] = make([]int, len(src[i])) copy(deep[i], src[i]) } deep[0][0] = 999 fmt.Println(src[0][0]) // 99 ← 安全
1.4 切片去重
方法一:排序后去重(会改变顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13
funcunique(s []int) []int { sort.Ints(s) j := 0 for i := 1; i < len(s); i++ { if s[i] != s[j] { j++ s[j] = s[i] } } return s[:j+1] }
unique([]int{3, 1, 2, 3, 1}) // [1 2 3]
方法二:用 map 去重(保持首次出现顺序)
1 2 3 4 5 6 7 8 9 10 11 12 13
funcuniqueMap(s []int) []int { seen := make(map[int]bool) result := make([]int, 0, len(s)) for _, v := range s { if !seen[v] { seen[v] = true result = append(result, v) } } return result }
uniqueMap([]int{3, 1, 2, 3, 1}) // [3 1 2]
1.5 切片反转
1 2 3 4 5 6 7
funcreverse(s []int) { for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { s[i], s[j] = s[j], s[i] } }
reverse([]int{1, 2, 3, 4, 5}) // [5 4 3 2 1]
🏗️ 二、结构体与容器结合
2.1 结构体切片 — “对象数组”
1 2 3 4 5 6 7 8 9 10 11 12 13 14
type Student struct { Name string Age int Score float64 }
funcfindByName(students []Student, name string) *Student { for i := range students { if students[i].Name == name { return &students[i] } } returnnil }
// 使用 if s := findByName(students, "Bob"); s != nil { s.Score = 90.0// 直接修改 }
过滤:
1 2 3 4 5 6 7 8 9 10 11
funcfilterByScore(students []Student, min float64) []Student { result := make([]Student, 0) for _, s := range students { if s.Score >= min { result = append(result, s) } } return result }
excellent := filterByScore(students, 90.0)
2.4 map 存结构体 vs 指针
存值 — 不能直接修改字段:
1 2 3 4 5 6 7 8 9
m := map[string]Student{"Alice": {"Alice", 20, 95.5}}
// ❌ 编译错误:cannot assign to struct field // m["Alice"].Score = 99
// ✅ 必须先取出、修改、再存回 s := m["Alice"] s.Score = 99 m["Alice"] = s
存指针 — 可以直接修改(推荐):
1 2 3 4 5 6
m := map[string]*Student{ "Alice": {"Alice", 20, 95.5}, }
// ✅ 直接修改 m["Alice"].Score = 99
2.5 切片转 map(泛型通用写法)
需要频繁按某个字段查找时,把切片转成 map:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// 泛型工具函数(Go 1.18+) funcToMap[Kcomparable, Vany](slice []V, keyFn func(V) K) map[K]V { m := make(map[K]V, len(slice)) for _, v := range slice { m[keyFn(v)] = v } return m }
// 查找 func(um *UserManager) GetUser(id int) (*User, bool) { um.mu.RLock() defer um.mu.RUnlock() u, ok := um.users[id] return u, ok }
// Top N 排名 func(um *UserManager) TopN(n int) []*User { um.mu.RLock() defer um.mu.RUnlock()
all := make([]*User, 0, len(um.users)) for _, u := range um.users { all = append(all, u) } sort.Slice(all, func(i, j int)bool { return all[i].Score > all[j].Score }) if n > len(all) { n = len(all) } return all[:n] }
// 平均分 func(um *UserManager) AvgScore() float64 { um.mu.RLock() defer um.mu.RUnlock() iflen(um.scores) == 0 { return0 } sum := 0 for _, s := range um.scores { sum += s } returnfloat64(sum) / float64(len(um.scores)) }