关于golang中的值传递和引用传递

1.在golang中,是值传递,即传递的方式是通过拷贝副本。而golang中是浅拷贝,没有深拷贝。
2.在golang中,所有的基本数据类型都是值类型。切片(slice),字典(map),通道(channel)都是引用类型

1.基本类型

例如下面的示例代码(demo.go):

package main

import "fmt"

func main() {
	array1 := [3]string{"yi", "er", "san"}
	fmt.Printf("The array: %v\n", array1)
	array2 := modifyArray(array1)
	fmt.Printf("The modified array: %v\n", array2)
	fmt.Printf("The original array: %v\n", array1)
}

func modifyArray(a [3]string) [3]string {
	a[1] = "modified"
	return a
}

执行后,控制台输出

laptop@localhost go_study % go run demo.go
The array: [yi er san]
The modified array: [yi modified san]
The original array: [yi er san]

可以看到,经过modifyArray函数后,array1的值没有发生改变,是因为在调用函数并传入array1时,传入的是array1的副本,在函数中对array1的任何修改都不会影响原始数组。

2.引用类型

这里以切片为例

package main

import "fmt"

func main() {
	slice1 := make([]string, 3)
	slice1[0] = "yi"
	slice1[1] = "er"
	slice1[2] = "san"
	fmt.Printf("The slice: %v\n", slice1)
	slice2 := modifySlice(slice1)
	fmt.Printf("The modified slice: %v\n", slice2)
	fmt.Printf("The original slice: %v\n", slice1)
}

func modifySlice(a []string) []string {
	a[1] = "modified"
	return a
}

执行后,控制台输出

laptop@localhost go_study % go run demo.go
The slice: [yi er san]
The modified slice: [yi modified san]
The original slice: [yi modified san]

可以看到slice1在传入modifySlice函数后,也发生了改变,这是因为modifySlice函数的形参接受的是slice1内存地址(引用指针)的副本,在函数中修改了它,本体也会被修改。

3.基本类型+引用类型

现在我们试试使用数组,但是数组的元素是引用类型(切片slice)

package main

import "fmt"

func main() {
	nestArray := [3][]string{
		[]string{"1", "2", "3"},
		[]string{"a", "b", "c"},
		[]string{"一", "二", "三"},
	}
	// 数组但是元素是切片(切片,字典,通道都是引用类型)
	modifyNestArray := modifyNestArray(nestArray)
	fmt.Printf("The modified nest array: %v\n", modifyNestArray)
	fmt.Printf("The original nest array: %v\n", nestArray)
}

func modifyNestArray(a [3][]string) [3][]string {
	a[1] = make([]string, 0)
	a[2][0] = "modified"
	return a
}

执行后,控制台输出

laptop@localhost go_study % go run demo.go 
The modified nest array: [[1 2 3] [] [modified 二 三]]
The original nest array: [[1 2 3] [a b c] [modified 二 三]]

可以看到,我们在函数中对数组的元素进行修改时,并不会影响原数组的元素。但是如果我们对数组中元素(切片)的内容进行修改时,会影响原始的数组中的元素(切片)的内容。

对于基本类型包含引用类型的情况,在作为参数传递的时候,本质上还是值传递,只不过作为数组元素的引用类型,他传递的值是指针(内存地址),所以函数内对数组的修改不会影响原先的数组,但是修改切片的内容会影响原先的内容。

# 随笔 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×