Golang随笔-生活工作点滴

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

2019-07-10  本文已影响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 指针的一个优势点吧。

上一篇下一篇

猜你喜欢

热点阅读