作用域为已声明标识符所表示的常量、类型、变量、函数或包在源代码中的作用范围。
Go 语言中变量可以在三个地方声明:
函数内定义的变量称为局部变量
函数外定义的变量称为全局变量
函数定义中的变量称为形式参数

# 局部变量

在函数体内声明的变量称之为局部变量,它们的作用域只在函数体内,参数和返回值变量也是局部变量。

因为之前也用过,因此不过多叙述,接下来用简单的代码展示一下局部变量

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func main() {
    var a, b, c int

    a = 10
    b = 20
    c = a + b

    fmt.Printf("结果: a = %d, b = %d and c = %d\n", a, b, c)
}

输出:

如上述代码,abc 三个变量在 main 函数中被声明,也就是 abc 的作用域在 main 函数当中,外部无法不声明直接引用这三个变量

# 全局变量

在函数体外声明的变量称之为全局变量,全局变量可以在整个包甚至外部包(被导出后)使用。

全局变量之所以被称为全局,也就是在整一个程序中都可以被引用。因此在函数体外进行声明,在任何函数当中都可以使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import "fmt"

var g int

func main() {

    var a, b int

    a = 10
    b = 20
    g = a + b

    fmt.Printf("结果: a = %d, b = %d and g = %d\n", a, b, g)
}

输出:

如上述程序可以知道,ab 依然为 main 函数中声明的局部变量,只能在 main 函数中使用,但 g 在函数外进行声明,因此 g 为全局变量,main 函数中也可以使用

这时候可以就会想到一个问题,全局变量和局部变量的变量名相同时会不会引起冲突呢?答案是并不会,但在函数体当中,会优先考虑该函数体中声明的全局变量,如下实例:

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "fmt"

var g int = 20

func main() {

    var g int = 10
    fmt.Printf("结果: g = %d\n", g)

}

输出:

可以看到变量名同为 g 时,main 函数中的优先输出是局部变量的 g 值

# 形式参数

形式参数会作为函数的局部变量来使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

var a int = 20

func main() {
    var a int = 10
    var b int = 20
    var c int = 0

    fmt.Printf("main()函数中 a = %d\n", a)
    c = sum(a, b)
    fmt.Printf("main()函数中 c = %d\n", c)
}

func sum(a, b int) int {
    fmt.Printf("sum() 函数中 a = %d\n", a)
    fmt.Printf("sum() 函数中 b = %d\n", b)

    return a + b
}

输出:

分别来解释一下输出和作用域,在两个函数之外的 a 毋庸置疑是全局变量,作用域在全局,但是 main 函数中也声明了变量 a,因此优先级高于全局的,输出为 10
。接着调用了 sum 函数,而在 sum 函数定义了 a,b 两个形参,作为局部变量,因此作用域仅在 sum 函数中,在接收到 main 函数中 a,b 的值传递后,输出的 a,b 值也就是 main 函数中 a,b 的值,为 10 和 20
。将返回的 a+b 值赋给了 c,因此 main 函数中输出的 c 值为 30

当函数中没有进行重新声明赋值时,默认使用全局变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

var a int = 20
var b int = 20

func main() {
    var c = 0
    c = sum(a, b)
    fmt.Printf("main() 函数中 c = %d\n", c)

}

func sum(a, b int) int {
    fmt.Printf("sum() 函数中 a = %d\n", a)
    fmt.Printf("sum() 函数中 b = %d\n", b)

    return a + b
}

输出:

# 初始化局部和全局变量

不同类型的局部和全局变量默认值为:

数据类型 初始化默认值


int 0
float32 0
pointer nil