Day 2: 深入探索复合类型 - 掌握Slice/Map核心操作

目录

  • Day 2: 深入探索复合类型 - 掌握Slice/Map核心操作
    • 1. 数组与切片(Slice)
      • 1.1 数组
        • 定义数组
        • 访问元素
      • 1.2 切片(Slice)
        • 定义切片
        • 切片操作
    • 2. 映射(Map)
      • 定义Map
      • 增删改查操作
    • 3. 字符串处理
      • 3.1 strings包
        • 常用函数
      • 3.2 strconv包
        • 常用函数
    • 4. 练习
      • 4.1 统计文本词频
        • 解答
      • 4.2 实现切片去重
        • 解答
    • 总结

Day 2: 深入探索复合类型 - 掌握Slice/Map核心操作

在Go语言中,复合类型和数据结构是编写高效程序的重要组成部分。本文将深入探讨数组、切片(Slice)、映射(Map)和字符串处理的相关操作,并通过两个练习(统计文本词频和实现切片去重)帮助你将理论转化为实践。

1. 数组与切片(Slice)

1.1 数组

数组是固定长度的元素序列,元素类型必须一致,且长度在定义时确定,无法动态调整。

定义数组
var arr [3]int = [3]int{1, 2, 3}  // 定义并初始化一个长度为3的整型数组
访问元素
fmt.Println(arr[0])  // 输出 1

数组虽然简单,但在实际开发中因其固定长度的限制,使用场景较少。接下来介绍更灵活的切片。

1.2 切片(Slice)

切片是基于数组的动态长度数据结构,支持伸缩操作,是Go中最常用的复合类型之一。

定义切片
s := []int{1, 2, 3}  // 直接创建并初始化一个切片
切片操作
  • append:向切片末尾添加元素,自动扩展容量。

    s = append(s, 4)  // s 变为 [1, 2, 3, 4]
    
  • copy:将一个切片的内容复制到另一个切片。

    dest := make([]int, len(s))  // 创建目标切片
    copy(dest, s)                // dest 现在是 s 的副本 [1, 2, 3, 4]
    
  • 切片表达式:提取切片或数组的子集,格式为 [start:end](包含 start,不包含 end)。

    sub := s[1:3]  // sub 为 [2, 3]
    

切片的灵活性使其成为处理动态数据的主要工具。


2. 映射(Map)

映射(Map)是键值对的无序集合,类似于其他语言中的字典或哈希表。键必须唯一,值可以重复。

定义Map

m := make(map[string]int)  // 创建一个空的Map,键为string,值为int

增删改查操作

  • 增/改:通过键赋值即可添加或更新元素。

    m["apple"] = 5  // 添加或更新键"apple"的值为5
    
  • :通过键获取值,并可检查键是否存在。

    value, exists := m["apple"]  // value=5, exists=true
    if !exists {
        fmt.Println("键不存在")
    }
    
  • :使用内置的delete函数删除键值对。

    delete(m, "apple")  // 删除键"apple"
    

Map 的无序性和高效查询特性使其非常适合存储和查找数据。


3. 字符串处理

Go语言提供了强大的字符串处理功能,主要依赖stringsstrconv两个标准库。

3.1 strings包

strings包包含了许多实用的字符串操作函数。

常用函数
  • strings.Split:按指定分隔符将字符串分割为切片。

    parts := strings.Split("a,b,c", ",")  // parts = ["a", "b", "c"]
    
  • strings.Join:将切片中的元素连接成字符串。

    str := strings.Join(parts, "-")  // str = "a-b-c"
    
  • strings.Contains:检查字符串是否包含某个子串。

    fmt.Println(strings.Contains("hello", "ell"))  // 输出 true
    

3.2 strconv包

strconv包用于字符串与其他基本数据类型之间的转换。

常用函数
  • strconv.Atoi:将字符串转换为整数。

    num, err := strconv.Atoi("123")  // num=123, err=nil
    if err != nil {
        fmt.Println("转换失败:", err)
    }
    
  • strconv.Itoa:将整数转换为字符串。

    str := strconv.Itoa(456)  // str="456"
    

这些工具让字符串处理变得简单高效。


4. 练习

4.1 统计文本词频

问题:编写一个函数,统计给定文本中每个单词的出现频率。

解答
package main

import (
    "fmt"
    "strings"
)

func wordFrequency(text string) map[string]int {
    words := strings.Fields(text)  // 按空白符分割文本
    freq := make(map[string]int)   // 创建Map存储词频
    for _, word := range words {
        freq[word]++  // 统计每个单词出现次数
    }
    return freq
}

func main() {
    text := "hello world hello go world go"
    fmt.Println(wordFrequency(text))  // 输出 map[go:2 hello:2 world:2]
}

解析:使用strings.Fields分割文本,然后用Map记录每个单词的出现次数。

4.2 实现切片去重

问题:编写一个函数,接收一个整型切片,返回去重后的切片(保留元素的首次出现顺序)。

解答
package main

import "fmt"

func uniqueSlice(nums []int) []int {
    seen := make(map[int]bool)  // 用Map记录已出现的元素
    result := []int{}           // 存储去重后的结果
    for _, num := range nums {
        if !seen[num] {         // 如果元素未出现过
            result = append(result, num)
            seen[num] = true
        }
    }
    return result
}

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

解析:借助Map记录元素是否出现过,保留首次出现的顺序,最终返回去重后的切片。


总结

本篇内容学习了Go语言中数组、切片、映射和字符串处理的核心操作,并通过词频统计和切片去重的练习巩固了知识。这些复合类型和数据结构是Go编程的基础,掌握它们将为后续学习更复杂的功能(如结构体和并发)打下坚实基础。

你可能感兴趣的:(golang学习,golang)