关于值传递和引用传递的解释
值传递
值传递的数据类型
基本类型
基本类型是Go语言自带的类型,比如数值类型、浮点类型、字符类型以及布尔类型,他们本质上是原始类型,也就是不可改变的,所以对他们进行操作,一般都会返回一个新创建的值,所以把这些值传递给函数时,其实传递的是一个值的副本。
func changeDate(name string) string{
name = name+"你的数据被改变了"
return name
}
func main() {
name:="董雷"
tmpName := changeDate(name)
fmt.Println(name)
fmt.Println(tmpName)
}
//返回结果
董雷
董雷你的数据被改变了
上面的案例name在changeDate方法中修改了值,但是并没有影响main中的name,也就是说,我们传递的时一个副本,并且返回一个新创建的字符串。
基本类型因为是拷贝的值,并且在对他进行操作的时候,生成的也是新创建的值(写时复制机制),所以这些类型在多线程里是安全的,我们不用担心一个线程的修改影响了另外一个线程的数据。
引用传递
引用类型和原始的基本类型恰恰相反,它的修改可以影响到任何引用到它的变量
引用类型有
- 切片、[]string
- map、mapp[string]string
- 接口、interface{}
- 函数类型、
- 管道(chan)
引用类型之所以可以引用,是因为我们创建引用类型的变量,其实是一个标头值,标头值里包含一个指针,指向底层的数据结构,当我们在函数中传递引用类型时,其实传递的是这个标头值的副本,它所指向的底层结构并没有被复制传递,这也是引用类型传递高效的原因。
案例
func changeDate(slice []string) []string {
slice[0] = "你的企片被改了"
return slice
}
func main() {
slice := []string{"我是切片"}
tmpSlice := changeDate(slice)
fmt.Println(slice)
fmt.Println(tmpSlice)
}
//返回结果
[你的企片被改了]
[你的企片被改了]
可以看到切片在函数里面修改了,main里面的变量也会一起被修改,所以是引用传递
结构类型
结构体是值传递,会复制一个新值,包括下面的子元素不管是什么类型都会被影响
如何实现引用传递 &结构体 这种方式
代码
type person struct {
age int
name []string
point *map[string]string
}
func modify(p person) {
p.age =p.age+10
p.name = []string{"王子"}
p.point = &map[string]string{"name":"李四"}
}
func main() {
tmpMap := make(map[string]string)
tmpMap["name"] = "站桑"
donglei := person{10,[]string{"董雷"},&tmpMap}
fmt.Println(donglei)
modify(donglei)
fmt.Println(donglei)
}
//返回结果
{10 董雷}
{10 董雷}
自定义类型
自定义类型的好处,最主要的就是就是可以对自定义类型添加方法
本作品采用《CC 协议》,转载必须注明作者和本文链接