美文网首页Golang随笔-生活工作点滴
Go 语言基础--函数&作用域

Go 语言基础--函数&作用域

作者: 邹志全 | 来源:发表于2019-07-10 22:46 被阅读13次

    访问标示

    go变量通常会出现在函数内部(局部变量,只出现在函数体内,只能够在函数内部使用),函数外变量(全局变量,可以通过包访问),函数参数(形式参数)
    go的访问形式并没有一个特殊的标识符来标记,而是通过首写字母的大小来控制的。大写意味着是一个可导出的变量(可以理解为公有访问),消协意味着是一个包内私有变量(不导出的),结构体内定一个变量同理。

    func privateFunc() {
        // 这是一个私有的函数
    }
    func PublicFunc() {
        // 这是一个公有函数
    }
    var privateVar int // 这是一个私有变量
    var PublicVar int // 这是一个公有变量
    type PublicStruct struct {
        var privateVar int // 这是一个结构体内私有变量
        var PublicVar int // 这是一个结构体内公有变量
        privateFunc(a int) // 这是一个结构体私有的函数
        PublicFunc() string// 这是一个结构体公有的函数
    }
    

    函数组成

    通常来说函数有这么几个部分组成,函数标示、函数名、出参、入参、函数体、函数名。
    func: 函数标示
    getNameById: 函数名
    id int64: 函数入参
    string: 函数出参
    {···}: 函数体

    func getNameById(id int64) string {···}
    
    值传递&引用传递&指针传递

    值传递:调用函数时将实际的参数copy一份到函数中
    引用传递:调用函数时将实际参数的地址传递到函数中
    指针传递:将实际变量的指针传递到函数中

    值传递&引用传递这些都是各种语言中经常讨论的一个话题,比如说Java 中就是完全按值传递,基础类型时copy一份传递到函数中,在函数内部对这个值进行更新毫无作用,传递一个对象的时候copy一份引用的值传递到函数内部,这也就是为什么 对这个引用值进行操作毫无作用,但是对于这个引用值指向的对象进行更新就有效。

    public static void main(string []args) {
        Student student = new Student();
        int tempInt = 2;
        update(student, tempInt);
    }
    public static void update(Student stu, int value) {
        stu.name = "23333"; // 更新有效
        stu = new Student(); // 更新无效
        value = 1; // 更新无效
    }
    

    go中和Java是类似的,完全遵循按值传递。
    对于基础变量,就是传递了一个值的拷贝
    对于map或者数组,将实际变量的地址的拷贝进行传递
    对于结构体,传递的是结构体的一份拷贝,注意一点内部的变量也是进行copy的。
    看一下demo就很清晰了:

    type Student struct {
        Name string
        Age int
        stuInfo map[string]string
    }
    var value = 10
    var stu = Student{"a", 9,map[string]string {"address":"qwer"}}
    var strs = []string {"1", "1", "2", "3"}
    
    func update(student Student, value int, strs []string)  {
        value = 1 // 更新无效
        student.Age = 1 // 更新无效
        student.stuInfo["address"] = "asdf" // 更新有效
        student = Student{} // 更新无效
        strs[1] = "0" // 更新有效
        strs = []string{} // 更新无效
    }
    

    但是go 相对于Java 非常灵活的是go增加了指针,我们就可以方便使用的指针进行操作了

    type Student struct {
        Name string
        Age int
        stuInfo map[string]string
    }
    var stu = Student{"a", 9,map[string]string {"address":"qwer"}}
    
    func update(student *Student) {
        student.Age = 1 // 更新有效
        student.stuInfo["address"] = "asdf" // 更新有效
        student = &Student{} // 传递了一个指针值的拷贝,函数外原指针不会受到影响
    }
    

    go 的指针不像是C指针那么危险,会正常有空指针,但是不会发生野指针,这也算是go 指针的一个优势点吧。

    相关文章

      网友评论

        本文标题:Go 语言基础--函数&作用域

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