第 4 章 - Go 语言变量与常量
Go 语言是一门静态类型的编程语言,这意味着在编写程序时,所有的变量和常量都必须明确地声明其类型。变量用于存储可变的数据,而常量则用于存储不可变的数据。在 Go 语言中,变量和常量的使用方式非常灵活,支持多种声明方式、初始化方式及作用域控制。
本章将详细介绍 Go 语言的变量与常量,包括它们的定义、初始化、作用域、以及常见的应用场景。通过具体的案例,您将能够更好地理解 Go 语言中的变量和常量的工作原理。
1. 变量声明与初始化
在 Go 中,变量的声明和初始化可以通过多种方式完成。我们首先来看几种基本的声明方式。
1.1 使用 var
关键字声明变量
Go 语言使用 var
关键字来声明变量,声明时可以选择是否初始化变量。
示例 1: 声明并初始化变量
goCopy Codepackage main
import "fmt"
func main() {
var age int = 25
fmt.Println(age)
}
在上述例子中,我们使用 var
关键字声明了一个名为 age
的变量,类型为 int
,并初始化为 25
。
示例 2: 声明变量但不初始化
goCopy Codepackage main
import "fmt"
func main() {
var age int
fmt.Println(age)
}
如果声明变量时不进行初始化,Go 会给变量赋予默认值。在这里,由于 age
的类型是 int
,它将被初始化为 0
。
1.2 使用简短声明语法 :=
Go 语言提供了更简洁的声明变量的方式:使用 :=
运算符。在此语法下,变量不仅会声明,还会被自动推断类型。
示例 3: 使用简短声明语法
goCopy Codepackage main
import "fmt"
func main() {
name := "Alice"
age := 30
fmt.Println(name, age)
}
在这个例子中,我们声明了 name
和 age
两个变量,并通过 :=
进行初始化。Go 会根据赋值的类型自动推断变量的类型,因此我们无需显式地声明类型。
1.3 多变量声明
Go 支持在一行中声明多个变量,可以提高代码的简洁性和可读性。
示例 4: 多变量声明
goCopy Codepackage 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 Codepackage 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 Codepackage 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 Codepackage main
import "fmt"
func main() {
var age int = 30 // 这是一个局部变量
fmt.Println(age)
}
在上面的例子中,age
变量仅在 main
函数内有效,无法在函数外部访问。
2.2 全局作用域
全局变量是指在函数外部声明的变量,它们可以在整个包中访问。
示例 8: 全局变量作用域
goCopy Codepackage main
import "fmt"
var globalVar = 100 // 这是一个全局变量
func main() {
fmt.Println(globalVar)
}
在这个例子中,globalVar
是一个全局变量,它在整个包内都可以访问。
2.3 变量的生命周期
Go 中的局部变量会在函数调用时被创建,并在函数执行完毕后被销毁。而全局变量则会在程序启动时被创建,直到程序退出时销毁。
示例 9: 变量的生命周期
goCopy Codepackage 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 Codepackage main
import "fmt"
const Pi = 3.14
func main() {
fmt.Println("Value of Pi:", Pi)
}
在这个例子中,Pi
是一个常量,它的值被设置为 3.14
,并且不能在程序运行时修改。
3.2 常量的类型
Go 语言中的常量在声明时不需要指定类型,Go 编译器会根据常量的值来推断类型。如果需要使用不同类型的常量,可以显式声明类型。
示例 11: 常量类型
goCopy Codepackage main
import "fmt"
const length = 10.5
const width = 5.5
const area = length * width
func main() {
fmt.Println("Area of rectangle:", area)
}
在这个例子中,length
和 width
是浮动类型常量,而 area
则是计算所得的结果。
3.3 iota 自动增量
Go 中的常量支持 iota
关键字,它是一个常量生成器,用于在常量声明中生成递增的数字。
示例 12: 使用 iota
生成常量
goCopy Codepackage 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 Codepackage main
import "fmt"
const globalConst = "I am global" // 全局常量
func main() {
const localConst = "I am local" // 局部常量
fmt.Println(globalConst)
fmt.Println(localConst)
}
在这个例子中,globalConst
是全局常量,localConst
是局部常量。globalConst
可以在整个包内访问,而 `