golang sync.Map defaults to value passing when passing parameters in functions

overview

I changed a piece of code today. When calling a function, a variable of sync.Map type is used as a parameter, and the value of the sync.Map variable is modified inside the function. After the function is processed, the external variable is not modified. Later, it is found that sync.Map is An ordinary structure, like all structures, when golang passes the structure type as a function parameter, it is passed by value, that is, a copy of the parameter is created and then passed to the function. This also means that if you modify the value of this copy inside the function, the original value will not be affected.

verification process

The function parameter type is *sync.Map

Judging from the running results, the modification inside the function affects the original variable.

func main() {
	var result sync.Map
	result.Store(10, 11)
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true  // 返回 false 则表示停止迭代
	})
	fmt.Println("---------------------------")
	GetTaskCountValueMap(&result) // 传的是指针类型
	fmt.Println("---------------------------")
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true
	})
}

func GetTaskCountValueMap(result *sync.Map) {
	for i := 0; i < 3; i++ {
		result.Store(i, i+1)
	}
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true
	})
}

output result

key=10 val=11
---------------------------
key=0 val=1
key=1 val=2
key=2 val=3
key=10 val=11
---------------------------
key=10 val=11
key=0 val=1
key=1 val=2
key=2 val=3

The function parameter type is sync.Map

Judging from the running results, the modification inside the function will not affect the original variable.

func main() {
	var result sync.Map
	result.Store(10, 11)
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true  // 返回 false 则表示停止迭代
	})
	fmt.Println("---------------------------")
	GetTaskCountValueMap(result) // 传的是普通结构体类型
	fmt.Println("---------------------------")
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true
	})
}

func GetTaskCountValueMap(result sync.Map) {
	for i := 0; i < 3; i++ {
		result.Store(i, i+1)
	}
	result.Range(func(key, value any) bool {
		fmt.Printf("key=%v val=%v\n", key, value)
		return true
	})
}

output result

key=10 val=11
---------------------------
key=10 val=11
key=0 val=1
key=1 val=2
key=2 val=3
---------------------------
key=10 val=11

Golang function parameter passing reminder

Structures, arrays, and primitive data types are all passed by value

In the Go language, whether it is a structure or a basic data type, when they are passed as function parameters, they are passed by value. If the value of the copy is modified inside the function, the original value will not be affected.

Slices and maps are passed by reference

Slices appear to be passed by value, but in fact the slice data structure contains pointers to the underlying array. This means that when you pass a slice to a function, although it is passed by value (that is, the data structure of the slice itself is copied), the copied slice and the original slice still share the same underlying array. Therefore, if you modify an element in the copied slice in the function, the corresponding element in the original slice will also be modified.

Similar to slices, maps pass references to underlying data structures

Guess you like

Origin blog.csdn.net/qq_41767116/article/details/132683407