go pointers are that simple

content

1. Pointers in Go language

Second, the pointer type, pointer address

Third, the pointer value

Fourth, the null pointer

Five, new and make

1、new

2、make

3. The difference between new and make


        Different from pointers in C/C++, pointers in Go language cannot perform offset and operation, and are safe pointers. To understand pointers in Go language, you need to know three concepts first: pointer type, pointer value, and pointer address .

1. Pointers in Go language

The function parameters in the Go language are all value copies. When we want to modify a variable, we can create a pointer variable pointing to the address of the variable. Pass data using pointers without copying the data. Type pointers cannot be offset and summed. Pointer operation in Go language is very simple, just need to remember two symbols: & (take address) and * (take value according to address) .

Second, the pointer type, pointer address

Each variable has an address at runtime, which represents the location of the variable in memory. In the Go language, the & character is used in front of the variable to "take the address" of the variable.

The value types (int, float, bool, string, array, struct) in the Go language have corresponding pointer types, such as: *int, *int64, *string, etc.

The syntax for taking a pointer to a variable is as follows:

ptr := &v    // v的类型为T

//其中:
v:代表被取地址的变量,类型为T
ptr:用于接收地址的变量,ptr的类型就为*T,称做T的指针类型。*代表指针。

for example:

func main() {
    a := 10
    b := &a
    fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078
    fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int
    fmt.Println(&b)                    // 0xc00000e018
}

Let's take a look at the illustration of b := &a:

 

 

Third, the pointer value

After using the & operator to take the address of a common variable, the pointer of this variable will be obtained, and then you can use the * operation on the pointer, that is, the pointer value, the code is as follows.

func main() {
    //指针取值
    a := 10
    b := &a // 取变量a的地址,将指针保存到b中
    fmt.Printf("type of b:%T\n", b)
    c := *b // 指针取值(根据指针去内存取值)
    fmt.Printf("type of c:%T\n", c)
    fmt.Printf("value of c:%v\n", c)
}

The output is as follows:

type of b:*int
type of c:int
value of c:10

Summarize:

The address operator & and the value operator * are a pair of complementary operators, & fetches the address, * fetches the value pointed to by the address according to the address.

The relationship and characteristics of variables, pointer addresses, pointer variables, addresses, and values ​​are as follows:

  • By taking the address (&) operation of a variable, you can get the pointer variable of this variable.
  • The value of the pointer variable is the pointer address
  • Perform a value (*) operation on a pointer variable to obtain the value of the original variable pointed to by the pointer variable

Example of passing pointer by value:

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
}

Fourth, the null pointer

  • When a pointer is defined and not assigned to any variable, its value is nil
  • Null pointer judgment

package main
import "fmt"

func main() {
    var p *string
    
    fmt.Println(p)
    fmt.Printf("p的值是%v\n", p)
    if p != nil {
        fmt.Println("非空")
    } else {
        fmt.Println("空值")
    }
}

Five, new and make

func main() {
    var a *int
    
    //这里直接赋值会报错
    *a = 100
    fmt.Println(*a)

    var b map[string]int
    b["测试"] = 100
    fmt.Println(b)
}

Executing the above code will cause panic, why?

1) For a variable of reference type in the Go language, we must not only declare it when using it, but also allocate memory space for it, otherwise our value will not be stored.

2) The declaration of value types does not need to allocate memory space, because they have allocated memory space by default when they are declared.

To allocate memory, it leads to today's new and make. In Go language, new and make are two built-in functions, which are mainly used to allocate memory.

1、new

new is a built-in function with the following function signature:

func new(Type) *Type


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

The new function is not commonly used. The new function is used to obtain a pointer of a type, and the corresponding value of the pointer is the zero value of the type. for example:

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 just declares a pointer variable a but it is not initialized. The pointer as a reference type needs to be initialized before it has memory space before it can be assigned a value. You should use the built-in new function to initialize a as follows, and then assign it normally:

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

2、make

        make is also used for memory allocation. Different from new, it is only used for memory creation of slice, map and chan, and the type it returns is these three types themselves, not their pointer types, because these three types are reference types, so there is no need to return pointers to them.

The function signature of the make function is as follows:

func make(t Type, size ...IntegerType) Type

The make function is irreplaceable. When we use slice, map, and channel, we all need to use make to initialize them before we can operate on them.

func main() {
    var b map[string]int
    b = make(map[string]int, 10)
    
    //或者直接
    b := make(map[string]int)
    
    b["测试"] = 100
    fmt.Println(b)
}

3. The difference between new and make

  • Both are used for memory allocation.
  • make is only used for the initialization of slice, map and channel, and the three reference types themselves are returned;
  • And new is used for memory allocation of type, and the value corresponding to the memory is type zero, and it returns a pointer to the type.

Guess you like

Origin blog.csdn.net/demored/article/details/124173796