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 二 三]]
可以看到,我们在函数中对数组的元素进行修改时,并不会影响原数组的元素。但是如果我们对数组中元素(切片)的内容进行修改时,会影响原始的数组中的元素(切片)的内容。