美文网首页
GO 一文搞懂指针和地址值的区别

GO 一文搞懂指针和地址值的区别

作者: 舍是境界 | 来源:发表于2020-10-21 22:13 被阅读0次

    GO 语言的指针和地址值

    go语言中的指针和地址值,在使用上常常具有迷惑性,主要是其特殊的*、&符号的使用,可能会让你摸不透,本文希望能讲清楚go语言的指针(pointer)和值(value)。
    这里先简单的对指针和地址值概念做一个定义:

    • 指针:指针是一个内存地址,代表了从何处找寻到实际值的一个位置
    • 地址值:对象实际值对象信息
      区别就比如一个房子的位置和实际房子

    为什么我们需要一个值的指针?

    这是因为go方法传递参数的方式导致的,go方法函数传递参数传递的是一个拷贝,看看下面的程序会输出什么?

      type Student struct {
        Name string
        Age int
    }
    func main(){
        student := Student{Name: "小红", Age: 8}
        AddAge(student)
        
        fmt.Println(student.Age)
    }
    
    func AddAge(s Student){
        s.Age += 1
    }
    

    答案是8,而不是9,因为AddAge函数修改的是学生的一个备份,而不是原始的学生对象
    如果你想正确正确给学生年龄增加的话,函数传递的需要是这个值的指针,如下所示:

    func main(){
        student := Student{Name: "小红", Age: 8}
        AddAge(&student)
    
        fmt.Println(student.Age)
    }
    
    func AddAge(s *Student){
        s.Age += 1
    }
    

    需要注意的是,这里我们的指针传递的仍然是一个拷贝,比如,如果你将s赋值给另外一个指针地址,不会影响原有的指针,这点可以自行实践下。

    应用考虑

    那在使用go语言开发的时候,何时该用指针何时改用地址值呢?比如考虑以下场景:

    1. 一个本地变量的赋值
    2. 结构体中的一个字段
    3. 方法返回的值
    4. 方法的参数
    5. 一个方法的接收者

    简单原则:当你不确定该使用哪种的时候,优先使用指针

    复合类型的使用

    如果考虑在数组、切片、map等复合对象中使用指针和值,比如:

    a := make([]Student, 0)
    //或者
    b := make([]*Student, 0) 
    

    很多开发者会认为b会更高效,但是被传递的都是一个切片的拷贝,切片本身就是一个引用,所以这里被传递的其实没有什么区别。

    总结

    对于指针和地址值的使用,大家需要牢记的一点就是go数据传递的不可变性,活学活用此特点,在无状态函数中此特性非常有用。

    相关文章

      网友评论

          本文标题:GO 一文搞懂指针和地址值的区别

          本文链接:https://www.haomeiwen.com/subject/vsqymktx.html