zoukankan      html  css  js  c++  java
  • 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用于类型的内存分配,并且内存对应的值为类型零值,返回的是指向类型的指针
  • 相关阅读:
    浅谈隔板法
    最短路spaf及dijkstra模板
    P1219 最优贸易
    P1211 街道赛跑
    图结构模板
    P1218 过路费
    使用Asp.net Identity 创建用户 、登录代码
    asp.net identity 介绍
    响应式图像
    glyphicon 图标的使用
  • 原文地址:https://www.cnblogs.com/guotianbao/p/12143182.html
Copyright © 2011-2022 走看看