头图

What is a pointer

We all know that the data when the program is running is stored in the memory, and every data stored in the memory has a number, and this number is the memory address. We can find the data stored in the memory according to this memory address, and the memory address can be assigned to a pointer. We can also simply understand that a pointer is a memory address.

Pointer declaration and definition

In Go language, to get a pointer, you can &
Example:

func main() {
  name := "微客鸟窝"
  nameP := &name //取地址
  fmt.Println("name变量值为:", name)
  fmt.Println("name变量的内存地址为:", nameP)
}
//运行结果:
//name变量值为: 微客鸟窝
//name变量的内存地址为: 0xc00004e240
  • The type of nameP pointer is *string
  • In Go language, * type name represents a corresponding pointer type
variableData in memoryMemory address
name := "Weike Bird's Nest"Weike Bird's Nest0xc00004e240
nameP := &name0xc00004e2400xc00004e360

As can be seen from the above table:

  1. The value of the common variable name is Weike Bird’s Nest, which is stored in the memory at memory address 0xc00004e240
  2. The value of the pointer variable namep is the memory address of the ordinary variable 0xc00004e240
  3. The value of the pointer variable nameP is stored in the memory at memory address 0xc00004e360
  4. Ordinary variables store data, pointer variables store the address of the data

var keyword declaration

We can also use the var keyword declaration

var nameP *string
nameP = &name

new function declaration

nameP := new(string)
nameP = &name

You can pass the type to this built-in new function, and it will return the corresponding pointer type.

Pointer operation

Emphasize here:
pointer variable is a variable, and the value of this variable is the pointer (memory address)!
pointer variable is a variable, the value of this variable is pointer (memory address)!
pointer variable is a variable, the value of this variable is pointer (memory address)!

  1. Get the value pointed to by the pointer:
    * number to the pointer variable money to get the data corresponding to the pointer variable value:

    nameV := *nameP
    fmt.Println("nameP指针指向的值为:",nameV) //nameP指针指向的值为: 微客鸟窝
  2. Modify the value pointed to by the pointer:

    *nameP = "公众号:微客鸟窝" //修改指针指向的值
    fmt.Println("nameP指针指向的值为:",*nameP)
    fmt.Println("name变量的值为:",name)
    //运行结果:
    //nameP指针指向的值为: 公众号:微客鸟窝
    //name变量的值为: 公众号:微客鸟窝
  3. We found that the value pointed to by the nameP pointer has been changed, and the value of the variable name has also been changed
  4. Because the memory where the variable name stores data is the memory pointed to by the pointer nameP, after this memory is modified by nameP, the value of the variable name is also modified.
  5. The pointer variable defined directly by the var keyword cannot be assigned, because its value is nil, which is the memory address that has not been pointed to

    //错误示例
    var intP *int
    *intP = 10  //错误,应该先给分配一块内存,内存地址作为变量 intP 的值,这个内存就可以存放 10 了。
    
    //应该使用
    var intP *int  //声明int类型的指针变量 intP
    intP = new(int) // 给指针分配一块内存
    *intP = 66 
    fmt.Println(":::",intP)  //::: 0xc0000ac088
    fmt.Println(*intP) //66
    //简短写法
    var intP := new(int)
    *intP=66

Pointer parameter

When a pointer is used as a parameter for a function, the value of the actual parameter can be changed in the function through the formal parameter:

func main() {
    name := "无尘"
    modify(&name)
    fmt.Println("name的值为:",name)
}
func modify(name *string)  {
    *name = "wucs"
}
//运行结果:
//name的值为: wucs

Pointer receiver

  1. If the receiver type is a reference type such as map, slice, channel, pointers are not used;
  2. If you need to modify the receiver, you need to use pointers;
  3. If the receiver is a relatively large type, you can consider using pointers, because the memory copy is cheap and efficient.

When to use pointers

  • Do not use pointers for reference types such as map, slice, and channel;
  • If you need to modify the internal data or state of the method receiver, you need to use a pointer;
  • If you need to modify the value of a parameter or internal data, you also need to use pointer type parameters;
  • If it is a relatively large structure, the memory must be copied every time the parameter is passed or the method is called, which takes up a lot of memory. At this time, you can consider using pointers;
  • There is no need to use pointers for small data types like int and bool;
  • If you need concurrency safety, do not use pointers as much as possible, and use pointers to ensure concurrency safety;
  • It's best not to nest pointers, that is, don't use a pointer to a pointer. Although the Go language allows this, it will make your code extremely complicated.

微客鸟窝
37 声望3 粉丝