Value types in the GO language:

Int, float, bool, array, sturct, etc

Value passing is when a function is called and a copy of the actual parameter is passed to the function so that the actual parameter is not affected if it is modified

When you declare a variable of value type, the compiler allocates a space on the stack where the value of the variable is stored

Reference types in the GO language:

Slice, Map, Channel, Interface, func, String, etc

Declare a variable of reference type, and the compiler allocates the instance’s memory on the heap

Struct string {byte* STR; struct string {byte* STR; intgo len; }; But because string can’t be modified, each operation on string can only generate a new object, so it looks and uses like a value type.

The so-called reference passing refers to passing the address of the actual parameter to the function when calling the function, so that the modification of the parameter in the function will affect the actual parameter.

Note that a reference type can change its value inside a function, but if a parameter is reassigned, no modification of the reassigned parameter will affect the external argument

Nil can be assigned to reference types (except string), error types, and pointer types

 

Pointer types in go:

A pointer variable points to the memory address of a value

When a pointer is defined without assigning any variables, its value is nil. Nil Pointers are also called null Pointers

A pointer variable is usually abbreviated to PTR

A reference type can be thought of as a wrapper around a pointer

Null pointer judgment:

if(ptr ! = nil) /* PTR not null */ if(PTR == nil) /* PTR is null */Copy the code

 

Example:

package main

import "fmt"

type pArr []int

func (p *pArr) oopFunc(a) {
    (*p)[3] = 111
}

type newFunc func(string)

func strFunc(s string) {
    fmt.Printf("%T ", s[1]) //uint8
    fmt.Println(s)          //hello world
}

type Person struct {
    Name   string
    Height int
}

func changeStruct(p Person) {
    p.Name = "Bill"
    p.Height = 160
}

func main(a) {

    // Use the slice pointer
    var ptr []*int
    i := 1
    ptr = append(ptr, &i)
    fmt.Println("ptr:", *ptr[0])

    // Structs are value types
    person := Person{
        "Zhang".180,
    }
    changeStruct(person)
    fmt.Println(person) / / {zhang 180}

    //func can be passed as an argument
    var nf newFunc
    nf = strFunc
    str := "hello world"
    nf(str) //uint8 hello world

    // Similar to object-oriented approach
    p := make(pArr, 4)
    p.oopFunc()
    fmt.Println("p:", p) //p: [0 0 0 111]

    // The value type cannot be changed
    num := 1
    valPass(num)
    fmt.Println("num:", num) //num: 1

    // Reference types can be changed in functions
    nums := []int{0.1.2.3}
    RefPass(nums)
    fmt.Println("nums:", nums) //nums: [0 100 2 3]

    // Parameters can change the value of a reference type, but cannot be reassigned
    RefPass2(nums)
    fmt.Println("nums:", nums) //nums: [0 100 2 3]

    The parameter can change the value of the pointer type
    n := new(int)
    *n = 111
    PointPass(n)
    fmt.Println("n:", *n) //n: 12

    // The parameter can change the value of the pointer type, but reassignment of the parameter does not affect the argument
    PointPass2(n)
    fmt.Println("n:", *n) //n: 12

}

// Reassign the pointer to the new address. Changes to the parameter will not affect the external arguments
func PointPass2(num *int) {
    num = new(int)
    *num = 13
}

// Pointer pass, common usage
func PointPass(num *int) {
    *num = 12
}

// Pass by reference, common usage, this will change the external argument
func RefPass(nums []int) {
    nums[1] = 100
}

// Reassign the parameter without changing the external argument. The parameter points to the new address
func RefPass2(nums []int) {
    nums = []int{9.8.7.6}}/ / value
func valPass(num int) {
    num = 5
}
Copy the code