• Title


    Go的指针

    指针变量:保存指针地址

    Go语言中的指针不能进行偏移和运算

    两个符号:&(取地址)和*(根据地址取值)

    指针地址和指针类型

    每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置

    Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型

    取变量指针

    ptr := &v    // v的类型为T
    
    • v:代表被取地址的变量,类型为 T
    • ptr:用于接收地址的变量,类型为*T,称为T的指针类型,*代表指针
    func main() {
      a := 10
      b := &a
      fmt.Printf("a: %d, ptr: %p
    ", a, &a)
      fmt.Printf("b: %p, type od b: %T
    ", b, b)
      fmt.Println(&b)
    }
    // a: 10, ptr: 0xc000014080
    // b: 0xc000014080, type od b: *int
    // 0xc00000c028
    

    指针取值

    新变量对普通变量使用&操作符取地址后会获得这个普通变量的地址

    新变量保存的是地址,新变量是一个指针

    *新变量 可以取到新变量这个指针所指向的值

    func main() {
      a := 10
      b := &a
      fmt.Printf("type of b: %T
    ", b)
      c := *b
      fmt.Printf("type of c: %T
    ", c)
      fmt.Printf("value of c: %v
    ", c)
    }
    // type of b: *int
    // type of c: int
    // value of c: 10
    

    取地址操作符&和取值操作符*是一对互补操作符

    &取出地址,*根据地址取出地址指向的值

    变量、指针地址、指针变量、取地址、取值 :

    • 取地址(&)操作,让新变量变成指针变量
    • 指针变量的值是指针地址
    • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值

    指针传值

    func modify1(x int) {
      x := 100
    }
    func modify2(x *int) {
      *x = 100
    }
    func main() {
      a := 10
      modify1(a)
      fmt.Println(a)  // 10
      modify2(&a)
      fmt.Println(a)  // 100
    }
    

    new和make

    错误事例

    func main() {
      var a *int
      *a = 100
      fmt.Println(*a)
      
      var b map[string]int
      b["hello"] = 100
      fmt.Peintln(b)
    }
    

    上面的代码会引发panic

    var a *int只是声明了一个指针变量a但是没有初始化

    指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值

    • Go语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储

    • 对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间

    • Go语言中new和make是内建的两个函数,主要用来分配内存

    new

    func new(Type) *Type
    
    • Type表示类型,new函数只接受一个参数,这个参数是一个类型
    • *Type表示类型指针,new函数返回一个指向该类型内存地址的指针

    new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值

    func main() {
      a := new(int)
      b := new(bool)
      fmt.Printf("%T
    ", a)
      fmt.Printf("%T
    ", b)
      fmt.Println(*a)
      fmt.Println(*b)
    }
    // *int
    // *bool
    // 0
    // false
    

    var声明指针变量后,需要用new初始化

    func main() {
      var a *int
      a = new(int)
      *a = 10
      fmt.Println(*a)
    }
    

    make

    make只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身

    func main() {
      var b map[string]int           // 声明b是一个map变量
      b = make(map[string]int, 10)   // 初始化map变量
      b["age"] = 25                  // 赋值
      fmt.Println(b)                 // map[age:25]
    }
    

    new和make的区别

    • 都是用来分配内存的
    • make只用于slice、map以及chan的内存创建,而且它返回的类型就是这三个类型本身
    • 而new用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针
  • 相关阅读:
    Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法输入日志标题
    Linux下安装oracle数据库提示DISPLAY not set. Please set the DISPLAY and try again。
    redhat 关机注销命令详解
    VirtualBox的四种网络连接方式
    修改RedHat的系统显示时间
    insufficient memory to configure kdump(没有足够的内存)解决方法(待验证、待解决)
    xen坑随笔 heartbeat dpkg垃圾数据库清除
    tomcat 监控脚本
    负载均衡随笔
    GIT命令介绍
  • 原文地址:https://www.cnblogs.com/guotianbao/p/12143182.html
Copyright © 2020-2023  润新知