第 4 章 - Go 语言变量与常量

Go 语言是一门静态类型的编程语言,这意味着在编写程序时,所有的变量和常量都必须明确地声明其类型。变量用于存储可变的数据,而常量则用于存储不可变的数据。在 Go 语言中,变量和常量的使用方式非常灵活,支持多种声明方式、初始化方式及作用域控制。

本章将详细介绍 Go 语言的变量与常量,包括它们的定义、初始化、作用域、以及常见的应用场景。通过具体的案例,您将能够更好地理解 Go 语言中的变量和常量的工作原理。

1. 变量声明与初始化

在 Go 中,变量的声明和初始化可以通过多种方式完成。我们首先来看几种基本的声明方式。

1.1 使用 var 关键字声明变量

Go 语言使用 var 关键字来声明变量,声明时可以选择是否初始化变量。

示例 1: 声明并初始化变量

goCopy Code
package main import "fmt" func main() { var age int = 25 fmt.Println(age) }

在上述例子中,我们使用 var 关键字声明了一个名为 age 的变量,类型为 int,并初始化为 25

示例 2: 声明变量但不初始化

goCopy Code
package main import "fmt" func main() { var age int fmt.Println(age) }

如果声明变量时不进行初始化,Go 会给变量赋予默认值。在这里,由于 age 的类型是 int,它将被初始化为 0

1.2 使用简短声明语法 :=

Go 语言提供了更简洁的声明变量的方式:使用 := 运算符。在此语法下,变量不仅会声明,还会被自动推断类型。

示例 3: 使用简短声明语法

goCopy Code
package main import "fmt" func main() { name := "Alice" age := 30 fmt.Println(name, age) }

在这个例子中,我们声明了 nameage 两个变量,并通过 := 进行初始化。Go 会根据赋值的类型自动推断变量的类型,因此我们无需显式地声明类型。

1.3 多变量声明

Go 支持在一行中声明多个变量,可以提高代码的简洁性和可读性。

示例 4: 多变量声明

goCopy Code
package main import "fmt" func main() { var name, country string = "Alice", "China" var age, year int = 30, 2024 fmt.Println(name, country, age, year) }

在这个例子中,我们同时声明了多个变量,并在声明时进行初始化。

1.4 类型推断

Go 语言的类型推断允许开发者不显式地声明变量类型,Go 编译器会根据变量的初始值自动推断出其类型。这样既提高了代码的简洁性,又能确保类型的安全性。

示例 5: 类型推断

goCopy Code
package main import "fmt" func main() { var x = 10 // x 是 int 类型 var y = 3.14 // y 是 float64 类型 var name = "Go" // name 是 string 类型 fmt.Printf("%v, %T\n", x, x) fmt.Printf("%v, %T\n", y, y) fmt.Printf("%v, %T\n", name, name) }

在这个示例中,虽然我们没有明确声明变量类型,但 Go 编译器通过变量的初始值推断出了它们的类型。

1.5 使用 new 创建指针

Go 语言还提供了 new 关键字来为变量分配内存并返回指向该内存的指针。

示例 6: 使用 new 关键字

goCopy Code
package main import "fmt" func main() { p := new(int) // 创建一个指向 int 类型的指针 fmt.Println(*p) // 输出 0,因为 int 的默认值是 0 *p = 42 fmt.Println(*p) // 输出 42 }

在这个例子中,new(int) 创建了一个指向 int 类型的指针 p,并通过解引用操作符 * 修改了其值。

2. 变量的作用域

在 Go 中,变量的作用域决定了变量在程序中可见的范围。变量的作用域分为两种:局部作用域和全局作用域。

2.1 局部作用域

局部变量是指在函数内部声明的变量,它们只能在函数内部访问。

示例 7: 局部变量作用域

goCopy Code
package main import "fmt" func main() { var age int = 30 // 这是一个局部变量 fmt.Println(age) }

在上面的例子中,age 变量仅在 main 函数内有效,无法在函数外部访问。

2.2 全局作用域

全局变量是指在函数外部声明的变量,它们可以在整个包中访问。

示例 8: 全局变量作用域

goCopy Code
package main import "fmt" var globalVar = 100 // 这是一个全局变量 func main() { fmt.Println(globalVar) }

在这个例子中,globalVar 是一个全局变量,它在整个包内都可以访问。

2.3 变量的生命周期

Go 中的局部变量会在函数调用时被创建,并在函数执行完毕后被销毁。而全局变量则会在程序启动时被创建,直到程序退出时销毁。

示例 9: 变量的生命周期

goCopy Code
package main import "fmt" var counter = 0 func increment() { counter++ } func main() { fmt.Println("Counter before increment:", counter) increment() fmt.Println("Counter after increment:", counter) }

在这个例子中,counter 是一个全局变量,它在 main 函数和 increment 函数中都可以访问。在函数调用过程中,counter 的值会被修改。

3. 常量声明与使用

常量是与变量类似,但其值一旦赋值后就不能更改。Go 使用 const 关键字来声明常量。常量不仅有助于提高代码的可读性,还可以减少魔法数字的使用,使代码更加清晰。

3.1 常量声明

常量的声明方式与变量类似,可以使用 const 关键字。

示例 10: 常量声明

goCopy Code
package main import "fmt" const Pi = 3.14 func main() { fmt.Println("Value of Pi:", Pi) }

在这个例子中,Pi 是一个常量,它的值被设置为 3.14,并且不能在程序运行时修改。

3.2 常量的类型

Go 语言中的常量在声明时不需要指定类型,Go 编译器会根据常量的值来推断类型。如果需要使用不同类型的常量,可以显式声明类型。

示例 11: 常量类型

goCopy Code
package main import "fmt" const length = 10.5 const width = 5.5 const area = length * width func main() { fmt.Println("Area of rectangle:", area) }

在这个例子中,lengthwidth 是浮动类型常量,而 area 则是计算所得的结果。

3.3 iota 自动增量

Go 中的常量支持 iota 关键字,它是一个常量生成器,用于在常量声明中生成递增的数字。

示例 12: 使用 iota 生成常量

goCopy Code
package main import "fmt" const ( A = iota // 0 B = iota // 1 C = iota // 2 ) func main() { fmt.Println(A, B, C) }

在上面的例子中,iota 用于生成从 0 开始的递增常量。

3.4 常量的作用域

常量的作用域与变量类似。常量可以是局部的,也可以是全局的。

示例 13: 局部常量与全局常量

goCopy Code
package main import "fmt" const globalConst = "I am global" // 全局常量 func main() { const localConst = "I am local" // 局部常量 fmt.Println(globalConst) fmt.Println(localConst) }

在这个例子中,globalConst 是全局常量,localConst 是局部常量。globalConst 可以在整个包内访问,而 `