关于值传递和引用传递的解释

值传递

值传递的数据类型

基本类型

基本类型是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 协议》,转载必须注明作者和本文链接
good good study day day up
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!