在 Go 语言中,我们可以在两个不同的作用域中声明变量:局部作用域和全局作用域。
变量作用域指定了我们可以访问变量的区域。例如,
func addNumbers() {
sum := 5 + 4
}
这里,sum 变量是在函数内部创建的,因此只能在其内部访问(局部作用域)。这种类型的变量称为局部变量。
根据作用域,我们可以将 Go 变量分为两种类型:
- 局部变量
- 全局变量
Go 局部变量
当我们在函数内部声明变量时,这些变量将具有局部作用域(在函数内)。我们无法在函数外部访问它们。
这些类型的变量称为局部变量。例如,
// Program to illustrate local variables
package main
import "fmt"
func addNumbers() {
// local variables
var sum int
sum = 5 + 9
}
func main() {
addNumbers()
// cannot access sum out of its local scope
fmt.Println("Sum is", sum)
}
输出
undefined: sum
这里,sum 变量是 `addNumbers()` 函数的局部变量,因此只能在该函数内部访问。
这就是为什么当我们尝试从 `main()` 访问该函数时会收到错误。
为了解决这个问题,我们可以返回局部变量的值并将其分配给 `main` 函数内的另一个变量。或者,我们可以将 sum 变量设为全局变量。
Golang 中的全局变量
当我们在 `main()` 函数之前声明变量时,这些变量将具有全局作用域。我们可以在程序的任何部分访问它们。
这些类型的变量称为全局变量。例如,
// Program to illustrate global variable
package main
import "fmt"
// declare global variable before main function
var sum int
func addNumbers () {
// local variable
sum = 9 + 5
}
func main() {
addNumbers()
// can access sum
fmt.Println("Sum is", sum)
}
输出
Sum is 14
这次我们可以从 `main()` 函数内部访问 sum 变量。这是因为我们将 sum 变量创建为全局变量。
// outside the function
var sum int
现在,sum 将在程序的任何作用域(区域)中都可访问。
常见问题
当我们声明局部变量和全局变量而不给它们赋值时,它们会被分配到它们的默认值。
在 Go 语言中,`int` 和 `float32` 类型的默认值是0。
// Program to illustrate the default values of global and local variables
package main
import "fmt"
// global variable
var variable1 int
func defaultValues() {
// local variable
var variable2 float32
fmt.Println(variable1) // 0
fmt.Println(variable2) // 0
}
func main() {
defaultValues()
}
在上面的示例中,我们初始化了局部变量和全局变量。无论在哪里初始化,`int` 和 `float32` 的默认值都是0。
如果我们有名称相同的局部变量和全局变量,编译器会优先处理局部变量。例如,
// Program to illustrate the priorities of variables
package main
import "fmt"
// define global variable
var random = "Global"
func main() {
// define local variable with same name
var random = "Local"
fmt.Println(random)
}
输出
Local
这里,局部变量和全局变量都具有公共名称 random。当我们打印 random 时,它会打印“Local”,而不是“Global”。这意味着编译器优先处理局部变量而不是全局变量。
在某些情况下,使用全局变量被认为是不好的做法。这是因为程序的任何部分都可以访问全局变量。
因此,当一个函数更改全局变量的值时,同一程序中的其他函数可能不知道更改后的值。这样,它可能会导致全局变量的值不一致。
让我们看一个例子。
// Program to find the temperature
package main
import "fmt"
// global variable
var temperature float32 = 35
func findTemp1() {
temperature = 43
}
func findTemp2() {
temperature = 29
}
func main() {
fmt.Println("Initial Value:", temperature)
findTemp1()
fmt.Println("Value after findTemp1():", temperature)
findTemp2()
fmt.Println("Value after findTemp2():", temperature)
}
输出
Initial Value: 35 Value after findTemp1(): 43 Value after findTemp2(): 29
这里,我们创建了 2 个函数来查找温度。当 `findTemp2()` 函数更改 temperature 的值时,`findTemp1` 可能不知道更改。因此,`findTemp1()` 假设该值与它定义的相同,并继续根据该值运行。
这可能导致意外的输出,并在大型程序中造成极大的混淆。