B数据结构.go

前言:在编程的世界中,数据结构是组织和存储数据的关键方式,它直接影响着程序的性能和效率。Go 语言作为一门简洁高效的编程语言,在数据结构的使用上也有其独特的优势和特点。 

目录

Go语言数据结构入门:数组、切片、映射、结构体、通道

一、数组:死板的储物柜

二、切片:哆啦a梦的百宝袋

三、映射:智能快递柜

        三兄弟对比表

四、结构体:你的专属数据集装箱

五、通道(Channel):Goroutine的传声筒

         通道类型详解

实战小项目:

        游戏角色管理器

        结构体+通道实战:多人在线游戏 

总结


Go语言数据结构入门:数组、切片、映射、结构体、通道

一、数组:死板的储物柜

想象你有一个储物柜,格子数量固定,放满就不能加了: 

// 记得先声明一下数组哦,一个能存放3本书的数组
var bookshelf [3]string

// 给柜子里的格子装上书
bookshelf[0] = "Go语言入门"
bookshelf[1] = "数据结构"
bookshelf[2] = "数据库原理"

// 我还想添加第四本书:bookshlef[3] = "西游记"
// 会报错哦,因为柜子装不了了就出现了越界错误

数组的特点:

  • 固定长度:像定死的储物柜
  • 严格编号:格子从0开始数
  • 值类型:复制时整个柜子搬走
newShelf := bookshelf // newShelf把我们的书柜搬走了,盗取我们的书
newShelf[0] = "盗版书,不要看" // 它是盗版的,不要看~

fmt.Println(bookshelf[0]) // 输出我们的第一本书名"Go语言入门"。

// 数组适合存放固定数量的东西,比如一周有七天。

    二、切片:哆啦a梦的百宝袋

    切片就像哆啦A梦的口袋,想装多少装多少

    // 创建哆啦A梦的百宝袋(空尼基哇的)
    var magicBag []string
    
    // 现在来给百宝袋塞道具
    magicBag = append(magicBag,"竹蜻蜓")
    magicBag = append(magicBag,"任意门","时光机")
    
    fmt.Println(magicBag) // 现在有了[竹蜻蜓 任意门 时光机]

    切片核心技能:

    • 自动扩容:袋子不够大时自动换大袋子

    • 灵活裁剪:想要哪段切哪段

    tools := magicBag[0:2] // 拿到前两个工具
    fmt.Println(tools)    // [竹蜻蜓 任意门]
    •  容量管理:袋子实际大小
    fmt.Printf("长度:%d 容量:%d", 
        len(magicBag), // 当前元素数 → 3
        cap(magicBag)) // 总容量 → 可能为4
    
    // 用户列表、商品展示等动态数据都用切片!
    
    

    三、映射:智能快递柜

    映射(map)就像小区快递柜,凭取件码秒找包裹

    // 初始化快递柜
    expressBox := map[string]string{
        "SF1001": "王先生的显卡",
        "JD2002": "李小姐的化妆品",
    }
    
    // 存新快递
    expressBox["YT3003"] = "张同学的考研资料"
    
    // 取快递(带检查)
    package, exists := expressBox["JD2002"]
    if exists {
        fmt.Println("找到包裹:", package) // 李小姐的化妆品
    } else {
        fmt.Println("取件码无效")
    }
    
    // 删除包裹
    delete(expressBox, "SF1001")

    映射的魔法:

    • 键值配对:一个钥匙开一个柜门

    • 闪电查找:比翻列表快N倍

    • 无序存储:快递柜不按顺序放

            三兄弟对比表

    特性 数组 切片 映射
    长度 固定 可变 可变
    查找方式 下标 下标 键(key)
    内存复制 整个复制 只复制指针 只复制指针
    使用频率 较低 较高
    典型场景 固定集合 动态列表 字典/配置

    四、结构体:你的专属数据集装箱

    结构体就像乐高积木,让你自由组合不同类型的数据,打造专属数据结构:

    // 定义玩家结构体(你的游戏角色蓝图)
    type Player struct {
        Name   string  // 字符串类型名字
        Level  int     // 整数类型等级
        Skills []string// 字符串切片技能
        Equip  struct { // 嵌套结构体装备
            Weapon string
            Armor  string
        }
    }
    
    // 创建玩家实例(组装乐高)
    p := Player{
        Name:  "暗夜刺客",
        Level: 99,
        Skills: []string{"潜行", "背刺", "毒刃"},
        Equip: struct {
            Weapon string
            Armor  string
        }{
            Weapon: "幽冥匕首",
            Armor:  "影舞者斗篷",
        },
    }
    
    // 访问结构体字段(操作你的角色)
    fmt.Println(p.Name + "手持" + p.Equip.Weapon) 
    // 输出:暗夜刺客手持幽冥匕首
    
    // 修改装备(升级武器!)
    p.Equip.Weapon = "灭世双刃"

    结构体超能力解析

    • 字段自由组合:混合int、string、slice等任意类型

    • 嵌套结构:装备里再套装备(套娃警告)

    五、通道(Channel):Goroutine的传声筒

    通道是Go并发的灵魂,让协程(Goroutine)安全传递数据

    // 主函数:指挥中心
    func main() {
        // 创建无缓冲通道(同步对讲机)
        msgChan := make(chan string)
        
        // 启动协程:前线侦察兵
        go scout(msgChan, "A区")
        
        // 接收侦察兵报告(阻塞等待)
        report := <-msgChan
        fmt.Println("收到报告:", report) // 输出:A区安全!
    }
    
    // 侦察兵函数
    func scout(ch chan string, area string) {
        time.Sleep(time.Second) // 模拟侦察耗时
        ch <- area + "安全!"    // 发送报告
    }
             通道类型详解
    类型 创建方式 特点 适用场景
    无缓冲通道 make(chan T) 发送后必须立即接收 强同步任务(如信号通知)
    有缓冲通道 make(chan T, 容量) 可存储多个值(队列) 生产消费模型
    // 有缓冲通道示例(快递仓库)
    packageChan := make(chan string, 3) // 容量3的仓库
    
    // 生产者协程:入库
    go func() {
        packageChan <- "包裹1"
        packageChan <- "包裹2"
        packageChan <- "包裹3"
    }()
    
    // 消费者:出库
    fmt.Println(<-packageChan) // 包裹1
    fmt.Println(<-packageChan) // 包裹2

     通道高级操作:

    // 1. 关闭通道(贴上封条)
    close(packageChan)
    
    // 2. 循环接收直到通道关闭
    for pkg := range packageChan {
        fmt.Println("处理:", pkg)
    }
    
    // 3. 多路选择(监听多个通道)
    select {
    case msg := <-msgChan:
        fmt.Println(msg)
    case <-time.After(time.Second): // 超时控制
        fmt.Println("响应超时!")
    }

    实战小项目:

            游戏角色管理器

    package main
    
    import "fmt"
    
    type Character struct {
        Name   string
        Level  int
        Weapon string
    }
    
    func main() {
        // 1. 创建角色切片
        players := []Character{
            {"刀客", 15, "青龙刀"},
            {"法师", 23, "火焰杖"},
        }
        
        // 2. 添加新角色
        newPlayer := Character{Name: "射手", Level: 10, Weapon: "穿云箭"}
        players = append(players, newPlayer)
        
        // 3. 创建角色ID映射
        playerMap := make(map[int]Character)
        for id, player := range players {
            playerMap[id] = player
        }
        
        // 4. 按ID查找角色
        searchID := 1
        if char, exists := playerMap[searchID]; exists {
            fmt.Printf("找到角色%d: %s (Lv.%d 武器:%s)\n", 
                searchID, char.Name, char.Level, char.Weapon)
        }
    }
    • 动态数据用切片,键值查找用映射,固定集合用数组

            结构体+通道实战:多人在线游戏 

    package main
    
    import (
    	"fmt"
    	"strconv"
    	"time"
    )
    
    type GameEvent struct {
    	PlayerID int
    	Action   string
    	Target   string
    }
    
    func main() {
    	// 游戏事件通道(100个事件缓冲)
    	eventChan := make(chan GameEvent, 100)
    
    	// 启动玩家协程
    	go playerHandler(1, "攻击BOSS", eventChan)
    	go playerHandler(2, "采集草药", eventChan)
    
    	// 事件处理器
    	for i := 0; i < 2; i++ {
    		event := <-eventChan
    		fmt.Printf("玩家%d: %s→%s\n",
    			event.PlayerID, event.Action, event.Target)
    	}
    }
    
    func playerHandler(id int, action string, ch chan GameEvent) {
    	time.Sleep(time.Duration(id) * time.Second)
    	ch <- GameEvent{
    		PlayerID: id,
    		Action:   action,
    		Target:   "地图" + strconv.Itoa(id),
    	}
    }
    

     程序执行结果:

    玩家1: 攻击BOSS→地图1  
    玩家2: 采集草药→地图2  

    总结

    数组、切片和映射是 Go 语言常用数据结构。数组固定长度,适合存储预定规模数据;切片灵活可变,适配不确定长度集合;映射通过键值对高效查找。结构体能构建复杂类型,通道助力协程通信。在游戏开发中,切片动态管理角色,映射快速定位信息。掌握这些结构特点,利于开发高效代码。

    你可能感兴趣的:(26字母学习:Go入门篇,数据结构,开发语言,学习方法,青少年编程,golang,后端,visual,studio,code)