11 指针

  • 与C/C++ 中的指针不同,Go 中的指针不能进行偏移和运算,是安全指针
    • 取地址符:&
    • 根据指针取值:*
  • 需要知道:指针地址、指针类型、指针取值

指针地址和指针类型

  • 每个变量运行时都有一个地址,代表变量在内存中的位置
  • 指针类型:*int
  • 取变量指针的语法:ptr := &v
    • v : 被取地址的变量
    • ptr接收地址的变量,ptr 的类型就为*T,称为T的指针类型

指针取值

  • 对普通变量使用 & 取地址后,会获得这个变量的指针
    • 可以对指针使用*操作,对指针取值
    • 根据指针去内存取值

总结: 取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。

变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:

  • 对变量进行取地址(&)操作,可以获得这个变量的指针变量
  • 指针变量的值是指针地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。
  • 定义函数时,可以传入地址,使用指针传值

new 和 make

  • Go 中对于引用类型的变量,我们在使用时,不仅要声明它,还要为其分配内存,否则其值无法存储

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

    • ```go
      func main() {
      var a *int
      *a = 100
      fmt.Println(*a)
      
      var b map[string]int
      b["沙河娜扎"] = 100
      fmt.Println(b)
      
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27

      * `new`, `make` 用来分配内存



      #### new

      * 内置函数

      * 函数原型:`func new(Type) *Type`

      * Type : new 只接受一个参数,是一个类型
      * *Type :new函数返回一个指向该类型内存地址的指针

      * 使用`new`得到是一个指针,并且该指针对应的值,为**该类型的零值**

      * 示例:

      ```go
      func main() {
      a := new(int)
      b := new(bool)
      fmt.Printf("%T\n", a) // *int
      fmt.Printf("%T\n", b) // *bool
      fmt.Println(*a) // 0
      fmt.Println(*b) // false
      }
  • 对于var a *int:

    • 只是声明了一个指针变量,但未初始化, 不能被赋值
    • 指针是引用类型,需要初始化才有内存空间
1
2
var a *int
a = new(int)

make

  • 也是用于内存分配

  • new 不同,只用于slice , map , chan 的内存创建

  • 而且函数返回的类型就是类型本身, 而非指针类型,因为这三种类型就是引用类型,所以没必要返回他们的指针

  • make 的原型:func make(t Type, size ...InterType) Type

  • 需要使用make 对slice, map,channel 进行初始化

    • m := make(map[string]int,10)
      

new 和 make 的区别

  • 二者都是用于内存分配
  • make 只用于slice, map, channel 的初始化,并且返回的还是这三个引用类型的本身
  • new 用于类型的内存分配,并且内存对应的值为 该类型的零值,**返回的是指向该类型的指针