第 4 章 - Go 语言变量与常量
1. 变量声明
在Go语言中,变量声明有多种方式。常见的变量声明方式包括使用 var
关键字、短变量声明和类型推断。
1.1 使用 var
关键字声明变量
这是最传统的方式,适用于显式声明变量的类型。
package main
import "fmt"
func main() {
var a int = 10
var b string = "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
1.2 短变量声明
短变量声明使用 :=
操作符,适用于在函数内部声明变量。编译器会根据赋值表达式的类型自动推断变量的类型。
package main
import "fmt"
func main() {
a := 10
b := "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
1.3 类型推断
Go语言支持类型推断,即编译器可以根据初始值自动推断变量的类型。这在使用 var
关键字声明变量时也可以实现。
package main
import "fmt"
func main() {
var a = 10
var b = "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
2. 常量定义
常量在Go语言中使用 const
关键字声明。常量的值在编译时确定,不能在运行时修改。
2.1 声明单个常量
package main
import "fmt"
func main() {
const pi float64 = 3.14159
const greeting = "Hello, World!"
fmt.Println("pi:", pi)
fmt.Println("greeting:", greeting)
}
2.2 声明多个常量
可以一次性声明多个常量,使用逗号分隔。
package main
import "fmt"
func main() {
const (
pi = 3.14159
e = 2.71828
phi = 1.61803
gravity = 9.8
)
fmt.Println("pi:", pi)
fmt.Println("e:", e)
fmt.Println("phi:", phi)
fmt.Println("gravity:", gravity)
}
3. 类型推断
类型推断是Go语言的一个重要特性,它使得代码更加简洁。编译器会根据初始值自动推断变量的类型。
3.1 简单类型推断
package main
import "fmt"
func main() {
a := 10 // int
b := "Hello, Go!" // string
c := 3.14 // float64
fmt.Println("a:", a)
fmt.Println("b:", b)
fmt.Println("c:", c)
}
3.2 复合类型推断
Go语言支持复杂的类型推断,例如数组、切片、映射等。
package main
import "fmt"
func main() {
arr := [3]int{1, 2, 3} // 数组
slice := []int{1, 2, 3, 4, 5} // 切片
map_ := map[string]int{"a": 1, "b": 2} // 映射
fmt.Println("Array:", arr)
fmt.Println("Slice:", slice)
fmt.Println("Map:", map_)
}
4. 综合示例
下面是一个综合示例,展示了变量声明、常量定义和类型推断的多种用法。
package main
import "fmt"
func main() {
// 使用 var 关键字声明变量
var age int = 30
var name string = "Alice"
// 短变量声明
height := 1.75
city := "New York"
// 常量定义
const pi float64 = 3.14159
const greeting = "Hello, World!"
// 复合类型推断
arr := [3]int{1, 2, 3}
slice := []int{1, 2, 3, 4, 5}
map_ := map[string]int{"a": 1, "b": 2}
// 打印所有变量和常量
fmt.Println("age:", age)
fmt.Println("name:", name)
fmt.Println("height:", height)
fmt.Println("city:", city)
fmt.Println("pi:", pi)
fmt.Println("greeting:", greeting)
fmt.Println("Array:", arr)
fmt.Println("Slice:", slice)
fmt.Println("Map:", map_)
}
5. 总结
通过上述示例,我们详细讲解了Go语言中的变量声明、常量定义和类型推断。这些基本概念是编写Go程序的基础,希望这些内容能帮助你更好地理解和使用Go语言。
当然,我们可以继续深入探讨更多关于变量和常量的高级用法,包括变量的作用域、多变量声明、常量的枚举和 iota 的使用等。下面是一些更详细的示例和解释。
6. 变量的作用域
变量的作用域决定了变量在代码中的可见性和生命周期。Go语言中有几种不同的作用域:
- 全局变量:在所有函数之外声明的变量,可以在整个包中访问。
- 局部变量:在函数内部声明的变量,只能在该函数内访问。
- 块作用域:在
{}
块内声明的变量,只能在该块内访问。
全局变量
package main
import "fmt"
// 全局变量
var globalVar int = 100
func main() {
fmt.Println("Global variable:", globalVar)
}
局部变量
package main
import "fmt"
func main() {
// 局部变量
localVar := 200
fmt.Println("Local variable:", localVar)
}
块作用域
package main
import "fmt"
func main() {
if true {
blockVar := 300
fmt.Println("Block variable inside if block:", blockVar)
}
// 下面的代码会报错,因为 blockVar 在 if 块外不可见
// fmt.Println("Block variable outside if block:", blockVar)
}
7. 多变量声明
Go语言允许一次声明多个变量,可以使用 var
关键字或短变量声明。
使用 var
关键字声明多个变量
package main
import "fmt"
func main() {
var a, b, c int = 1, 2, 3
var x, y string = "Hello", "World"
fmt.Println("a:", a, "b:", b, "c:", c)
fmt.Println("x:", x, "y:", y)
}
使用短变量声明声明多个变量
package main
import "fmt"
func main() {
a, b, c := 1, 2, 3
x, y := "Hello", "World"
fmt.Println("a:", a, "b:", b, "c:", c)
fmt.Println("x:", x, "y:", y)
}
8. 常量的枚举和 iota
Go语言中的 iota
是一个特殊的常量生成器,可以用于生成一系列相关的常量值。iota
在每个 const
块中从0开始递增。
枚举常量
package main
import "fmt"
func main() {
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
fmt.Println("Sunday:", Sunday)
fmt.Println("Monday:", Monday)
fmt.Println("Tuesday:", Tuesday)
fmt.Println("Wednesday:", Wednesday)
fmt.Println("Thursday:", Thursday)
fmt.Println("Friday:", Friday)
fmt.Println("Saturday:", Saturday)
}
使用 iota 生成二进制标志
package main
import "fmt"
func main() {
const (
Read = 1 << iota // 1
Write // 2
Execute // 4
All = Read | Write | Execute // 7
)
fmt.Println("Read:", Read)
fmt.Println("Write:", Write)
fmt.Println("Execute:", Execute)
fmt.Println("All:", All)
}
9. 综合示例
下面是一个综合示例,展示了变量的作用域、多变量声明和常量的枚举及 iota 的使用。
package main
import "fmt"
// 全局变量
var globalVar int = 100
func main() {
// 局部变量
localVar := 200
fmt.Println("Global variable:", globalVar)
fmt.Println("Local variable:", localVar)
// 块作用域
if true {
blockVar := 300
fmt.Println("Block variable inside if block:", blockVar)
}
// 多变量声明
var a, b, c int = 1, 2, 3
var x, y string = "Hello", "World"
fmt.Println("a:", a, "b:", b, "c:", c)
fmt.Println("x:", x, "y:", y)
// 使用短变量声明
d, e, f := 4, 5, 6
z, w := "Hi", "There"
fmt.Println("d:", d, "e:", e, "f:", f)
fmt.Println("z:", z, "w:", w)
// 常量的枚举和 iota
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
fmt.Println("Sunday:", Sunday)
fmt.Println("Monday:", Monday)
fmt.Println("Tuesday:", Tuesday)
fmt.Println("Wednesday:", Wednesday)
fmt.Println("Thursday:", Thursday)
fmt.Println("Friday:", Friday)
fmt.Println("Saturday:", Saturday)
const (
Read = 1 << iota // 1
Write // 2
Execute // 4
All = Read | Write | Execute // 7
)
fmt.Println("Read:", Read)
fmt.Println("Write:", Write)
fmt.Println("Execute:", Execute)
fmt.Println("All:", All)
}
10. 总结
通过上述示例,我们详细讲解了Go语言中的变量作用域、多变量声明、常量的枚举和 iota
的使用。这些高级用法可以帮助你编写更加简洁和高效的Go代码。希望这些内容能帮助你更好地理解和使用Go语言。
11. 变量的初始化
在Go语言中,变量可以在声明时初始化,也可以在声明后初始化。未初始化的变量会被赋予其类型的零值。
11.1 声明时初始化
package main
import "fmt"
func main() {
var a int = 10
var b string = "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
11.2 声明后初始化
package main
import "fmt"
func main() {
var a int
var b string
a = 10
b = "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
12. 零值
在Go语言中,未初始化的变量会被赋予其类型的零值。不同类型的零值如下:
int
,uint
,int8
,int16
,int32
,int64
,uint8
,uint16
,uint32
,uint64
: 0float32
,float64
: 0.0bool
: falsestring
: “”- 指针、函数、接口、切片、通道、映射: nil
示例
package main
import "fmt"
func main() {
var a int
var b float64
var c bool
var d string
var e *int
var f []int
var g map[string]int
var h chan int
fmt.Println("a:", a) // 0
fmt.Println("b:", b) // 0.0
fmt.Println("c:", c) // false
fmt.Println("d:", d) // ""
fmt.Println("e:", e) // nil
fmt.Println("f:", f) // nil
fmt.Println("g:", g) // nil
fmt.Println("h:", h) // nil
}
13. 常量表达式
常量表达式是在编译时计算的,可以包含常量、字面量和某些内置函数(如 len
、cap
、real
、imag
、complex
、unsafe.Sizeof
等)。
示例
package main
import "fmt"
func main() {
const (
a = 10
b = a + 5
c = len("Hello, Go!")
d = unsafe.Sizeof(a) // 需要导入 "unsafe" 包
)
fmt.Println("a:", a)
fmt.Println("b:", b)
fmt.Println("c:", c)
fmt.Println("d:", d)
}
14. 最佳实践
14.1 使用短变量声明
在函数内部,尽量使用短变量声明 :=
,使代码更加简洁。
package main
import "fmt"
func main() {
a := 10
b := "Hello, Go!"
fmt.Println("a:", a)
fmt.Println("b:", b)
}
14.2 避免全局变量
尽量避免使用全局变量,因为它们会增加代码的耦合度和复杂性。尽量将变量的作用域限制在需要的地方。
package main
import "fmt"
func main() {
// 局部变量
localVar := 200
fmt.Println("Local variable:", localVar)
}
14.3 使用常量代替魔法数
使用常量代替代码中的“魔法数”(没有明确含义的数字),可以使代码更具可读性和可维护性。
package main
import "fmt"
const (
MaxUsers = 100
MinAge = 18
)
func main() {
users := 95
age := 20
if users < MaxUsers && age >= MinAge {
fmt.Println("User can join the system.")
} else {
fmt.Println("User cannot join the system.")
}
}
15. 综合示例
下面是一个综合示例,展示了变量的初始化、零值、常量表达式和一些最佳实践。
package main
import (
"fmt"
"unsafe"
)
// 全局变量
var globalVar int = 100
func main() {
// 局部变量
localVar := 200
fmt.Println("Global variable:", globalVar)
fmt.Println("Local variable:", localVar)
// 零值
var a int
var b float64
var c bool
var d string
var e *int
var f []int
var g map[string]int
var h chan int
fmt.Println("a:", a) // 0
fmt.Println("b:", b) // 0.0
fmt.Println("c:", c) // false
fmt.Println("d:", d) // ""
fmt.Println("e:", e) // nil
fmt.Println("f:", f) // nil
fmt.Println("g:", g) // nil
fmt.Println("h:", h) // nil
// 常量表达式
const (
aConst = 10
bConst = aConst + 5
cConst = len("Hello, Go!")
dConst = unsafe.Sizeof(aConst)
)
fmt.Println("aConst:", aConst)
fmt.Println("bConst:", bConst)
fmt.Println("cConst:", cConst)
fmt.Println("dConst:", dConst)
// 最佳实践
users := 95
age := 20
const (
MaxUsers = 100
MinAge = 18
)
if users < MaxUsers && age >= MinAge {
fmt.Println("User can join the system.")
} else {
fmt.Println("User cannot join the system.")
}
}
16. 总结
通过上述示例,我们详细讲解了Go语言中的变量初始化、零值、常量表达式以及一些最佳实践。这些知识点有助于你编写更加清晰、高效和可维护的Go代码。希望这些内容能帮助你更好地理解和使用Go语言。如果你有任何问题或需要进一步的解释,请随时提问!