baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • 华仔聊技术

  • 业务设计

  • 场景设计

  • 运维

  • 安全

  • 面试

  • mac相关工具推荐

  • 开发工具

  • 人工智能

  • 推荐

  • 阅读

  • 工具

  • 计划

  • 产品

  • 云原生

  • go

    • 基础
    • go项目
    • go channel
    • go list
    • go testing模块
    • go指针
      • go实现LRU
      • go数据结构的内存实现
      • go interfaces
      • go项目分包相关
      • 协程实现原理
      • 垃圾回收与写屏障
      • gin
      • go中flag的使用
      • go dig
      • linux环境快速搭建go
    • QVM

    • 软件设计师

    • 极客时间

    • 单元测试

    • 其他
    • go
    xugaoyi
    2023-08-12
    目录

    go指针

    # 什么是指针

    写代码的时候,我们通过变量就可以操作存储在内存中的值,进行赋值、加减运算等。大家有没有想过,变量代表什么呢?其实,一个变量对应一段内存空间,这段空间就存储了该变量相对应类型的值。指针的值就对应变量的地址,只通过指针,就可以更新或者读取变量的值,而不需要用到变量名。

    csharp复制代码var i int = 10      //声明变量i,并初始化为10
    var ptr *int = &i 
    fmt.Println(ptr,*ptr)
    // 0xc000018060 10  指针变量ptr存储的是i地址,*ptr对应指针指向的变量的值
    *ptr = 12  				// i=12  更新指针指向的变量的值
    fmt.Println(*ptr,i)		// 12 12
    
    1
    2
    3
    4
    5
    6

    上面这段代码,声明了*int 类型的指针变量 ptr ,通过取址运算符&获得指向整型变量 i 的地址。可以说,指针ptr指向变量i,或者说ptr指针保存了变量i的地址。

    # 指针声明

    通过上面一段话的解释,相信大家对指针有了比较清晰的认识:指针指向一个变量的内存地址。要想使用指针,必须先声明,格式如下:

    csharp复制代码var var_name *var_type
    // var_name 指针名称,var_type 指针所指向的变量的类型
    go复制代码var i int = 10
    str := "go"
    var ip *int         // *int类型的指针
    var pstr *string    // *string类型的指针
    ip = &i
    pstr = &str
    fmt.Println(*ip,*pstr)     // 10 go
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    注意:*int类型的指针,说明该指针指向的一定是int类型的变量,*string类型也类似。

    go复制代码str := "go"
    var ip *int
    ip = &str  // 编译不会通过
    
    1
    2
    3

    *int 类型的指针,指向的变量若是string类型的,编译器编译的时候就会报错:

    python
    复制代码cannot use &str (type *string) as type *int in assignment
    
    1
    2

    # 如何使用指针

    文章写到这里,关于如何使用指针,其实上文已经列出来了,主要经过三个步骤:声明、赋值和访问指针指向的变量的值

    go复制代码x,y := 1,"go"
    var px *int = &x    	// 1、声明并初始化
    var py = &y				// 2、省略指针类型,编译器自动判断
    //px,py := &x,&y		// 3、使用 :=
    fmt.Println(*px,*py) 	// 1 go   访问
    
    1
    2
    3
    4
    5

    # 关于空指针

    一个指针已声明而没有赋值时,称为空指针,为 nil 。任何类型的指针的零值都是 nil。

    csharp复制代码var ip *int
    fmt.Println(ip)							// nil
    fmt.Printf("ip 的值为:%x", ip)			// ip 的值为:0
    
    1
    2
    3

    如果ip != nil 为真,那么p是指向某个有效变量。指针之间也是可以进行相等测试的,只有当它们指向同一个变量或全部是nil时才相等。

    go复制代码1、指向同一个变量 true
    x,_ := 1,1
    px,py := &x,&x
    fmt.Println(px == py) 
     
    2、指向不同变量 false
    x,y := 1,1
    px,py := &x,&y
    fmt.Println(px == py)
    
    3、两个nil指针 true
    var px *int
    var py *int
    fmt.Println(px == py)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    # 指针作为函数参数使用

    指针包含的是一个变量的地址,如果将一个指针作为参数传递给函数,就可以通过指针来更新变量的值。

    css复制代码func a(p *int){
    	*p++
    }
    
    i := 10
    fmt.Println(i)      // 10
    a(&i);
    fmt.Println(i)		// 11
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 不常用的new函数

    给大家介绍下new函数,内建的new函数也是一种创建变量的方法,new(type)表示创建一个type类型的匿名变量,并初始化为type类型的零值,返回变量的地址,指针类型为*type。

    go复制代码p := new(int)   	// p, *int 类型, 指向匿名的 int 变量
    fmt.Println(*p) 	// 0
    *p = 2          	// 设置 int 匿名变量的值为 2
    fmt.Println(*p) 	// 2
    
    1
    2
    3
    4

    用new函数创建变量和普通变量声明语句方式创建变量没有什么区别,除了不需要声明一个临时变量的名字外。 下面的两个函数有着相同的行为:创建变量,并返回变量地址

    csharp复制代码func newA() *int {
        return new(int)
    }
    func newB() *int {
        var i int
        return &i
    }
    
    1
    2
    3
    4
    5
    6
    7

    每次调用new函数都会返回新的变量的地址:

    go复制代码p := new(int)
    q := new(int)
    fmt.Println(p,q)   // 0xc000018060 0xc000018068
    
    1
    2
    3
    编辑 (opens new window)
    上次更新: 2024/02/22, 14:03:19
    go testing模块
    go实现LRU

    ← go testing模块 go实现LRU→

    最近更新
    01
    spark基础
    02-22
    02
    mysql读写分离和分库分表
    02-22
    03
    数据库迁移
    02-22
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式