章工运维 章工运维
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)

章工运维

业精于勤,荒于嬉
首页
  • linux
  • windows
  • 中间件
  • 监控
  • 网络
  • 存储
  • 安全
  • 防火墙
  • 数据库
  • 系统
  • docker
  • 运维工具
  • other
  • elk
  • K8S
  • ansible
  • Jenkins
  • GitLabCI_CD
  • 随笔
  • 面试
  • 工具
  • 收藏夹
  • Shell
  • python
  • golang
友链
  • 索引

    • 分类
    • 标签
    • 归档
    • 首页 (opens new window)
    • 关于我 (opens new window)
    • 图床 (opens new window)
    • 评论 (opens new window)
    • 导航栏 (opens new window)
周刊
GitHub (opens new window)
  • python

  • shell

  • go

    • go基础

      • 指针
        • 数组
        • 切片
        • 字典
        • 结构体
        • 匿名组合
        • 方法
        • 接口
        • error接口
        • panic使用
      • Init函数和main函数
      • 下划线
      • go报错问题收集
      • Redis和MySQL结合的Web服务示例
      • go定义json数据
      • 使用go和vue编写学生管理系统
      • gin框架探索
    • 编程
    • go
    • go基础
    章工运维
    2024-11-14
    目录

    指针

    在Go语言中,指针是一个变量,它存储了另一个变量的内存地址。与C/C++类似,Go语言也支持指针,但不支持指针运算。指针在Go中非常重要,因为它能高效地传递数据,避免不必要的内存拷贝。

    # 1. 指针的基本概念

    在Go中,指针类型使用*表示。例如,*int表示一个指向int类型的指针,**string表示一个指向string指针的指针。

    要获取变量的地址,使用&操作符;而要访问指针指向的值,则使用*操作符(解引用)。

    var a int = 42
    var p *int = &a   // p是一个指向a的指针
    
    fmt.Println(p)    // 输出a的地址
    fmt.Println(*p)   // 输出a的值,通过指针p解引用
    
    1
    2
    3
    4
    5

    # 2. 指针的使用场景

    指针通常用于以下场景:

    • 修改函数内外部变量的值:如果需要在函数内修改参数的值,使用指针传递参数可以在函数内部直接修改外部变量。
    • 减少内存复制开销:传递大对象或结构体时,使用指针可以避免对整个对象的拷贝,提升效率。
    • 构建数据结构:像链表、树等数据结构往往依赖指针来链接节点。

    # 3. 使用指针修改变量的值

    在Go中,函数参数是按值传递的,意味着传递的只是值的副本。若需要修改原值,可以通过指针实现。

    func updateValue(num *int) {
        *num = 50 // 修改num指针指向的变量的值
    }
    
    func main() {
        val := 100
        updateValue(&val)
        fmt.Println(val) // 输出50,表明val的值已被修改
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # 4. 使用指针避免内存拷贝

    当需要传递一个大对象时,可以通过指针传递来减少拷贝开销。例如传递一个结构体:

    type User struct {
        ID   int
        Name string
    }
    
    func updateUserName(user *User, newName string) {
        user.Name = newName // 直接修改指针指向的User的Name字段
    }
    
    func main() {
        user := User{ID: 1, Name: "Alice"}
        updateUserName(&user, "Bob")
        fmt.Println(user.Name) // 输出Bob
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 5. 指针与切片

    在Go中,切片(slice)和映射(map)是引用类型,直接传递它们的副本不会导致数据的拷贝,因此不需要通过指针传递。然而,如果需要修改切片的长度或容量,可以通过传递指针来实现。

    func appendElement(s *[]int, element int) {
        *s = append(*s, element) // 修改切片的长度
    }
    
    func main() {
        nums := []int{1, 2, 3}
        appendElement(&nums, 4)
        fmt.Println(nums) // 输出[1 2 3 4]
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    # 6. 指针与方法接收者

    结构体的方法可以有值接收者或指针接收者。使用指针接收者可以直接修改结构体的字段,且对大对象更高效。

    type Counter struct {
        value int
    }
    
    // 使用指针接收者
    func (c *Counter) Increment() {
        c.value++
    }
    
    func main() {
        counter := Counter{value: 10}
        counter.Increment()
        fmt.Println(counter.value) // 输出11
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 7. nil指针

    在Go中,未初始化的指针默认为nil。使用指针前应检查其是否为nil,以避免运行时错误。

    func printValue(p *int) {
        if p != nil {
            fmt.Println(*p)
        } else {
            fmt.Println("Pointer is nil")
        }
    }
    
    func main() {
        var ptr *int
        printValue(ptr) // 输出Pointer is nil
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    # 8. 使用new和make初始化指针

    • new:用于分配内存并返回指向该类型的指针,适用于基本类型和结构体。
    • make:仅用于分配并初始化slice、map和channel。
    p := new(int)    // p指向一个int类型的内存地址
    *p = 100
    fmt.Println(*p)  // 输出100
    
    s := make([]int, 0)
    fmt.Println(s)   // 输出[]
    
    1
    2
    3
    4
    5
    6

    # 总结

    指针在Go中非常实用,它提供了高效的数据传递方式,并允许在函数内修改变量值。熟练掌握指针,可以编写出更高效、灵活的代码。

    微信 支付宝
    上次更新: 2024/11/14, 16:29:25

    ← 批量拿取多台服务器的日志文件 数组→

    最近更新
    01
    不花一分钱从0到1建站教程
    04-22
    02
    批量拿取多台服务器的日志文件
    04-21
    03
    高德MCP智能体搞定旅游计划
    04-19
    更多文章>
    Theme by Vdoing | Copyright © 2019-2025 | 点击查看十年之约 | 鄂ICP备2024072800号
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式