258 lines
6.8 KiB
Go
258 lines
6.8 KiB
Go
/*
|
||
02-variables.go - Go 语言变量详解
|
||
|
||
学习目标:
|
||
1. 掌握变量声明的多种方式
|
||
2. 理解 Go 的类型推断
|
||
3. 学会使用短变量声明
|
||
4. 了解变量的作用域
|
||
5. 掌握零值的概念
|
||
|
||
知识点:
|
||
- var 关键字声明
|
||
- 短变量声明 :=
|
||
- 类型推断
|
||
- 零值
|
||
- 变量作用域
|
||
- 多变量声明
|
||
*/
|
||
|
||
package main
|
||
|
||
import "fmt"
|
||
|
||
// 包级别变量声明(全局变量)
|
||
var globalVar = "我是全局变量"
|
||
var (
|
||
// 使用括号可以声明多个变量
|
||
packageVar1 = "包变量1"
|
||
packageVar2 = "包变量2"
|
||
packageVar3 int = 100
|
||
)
|
||
|
||
func main() {
|
||
fmt.Println("=== Go 语言变量详解 ===\n")
|
||
|
||
// 演示各种变量声明方式
|
||
demonstrateVariableDeclaration()
|
||
|
||
// 演示零值
|
||
demonstrateZeroValues()
|
||
|
||
// 演示类型推断
|
||
demonstrateTypeInference()
|
||
|
||
// 演示多变量声明
|
||
demonstrateMultipleDeclaration()
|
||
|
||
// 演示变量作用域
|
||
demonstrateScope()
|
||
|
||
// 演示变量赋值和修改
|
||
demonstrateAssignment()
|
||
}
|
||
|
||
// demonstrateVariableDeclaration 演示变量声明的不同方式
|
||
func demonstrateVariableDeclaration() {
|
||
fmt.Println("1. 变量声明方式:")
|
||
|
||
// 方式1: var 关键字 + 类型声明
|
||
var name string
|
||
name = "张三"
|
||
fmt.Printf(" 方式1 - var name string: %s\n", name)
|
||
|
||
// 方式2: var 关键字 + 类型声明 + 初始化
|
||
var age int = 25
|
||
fmt.Printf(" 方式2 - var age int = 25: %d\n", age)
|
||
|
||
// 方式3: var 关键字 + 类型推断
|
||
var city = "北京" // Go 会自动推断为 string 类型
|
||
fmt.Printf(" 方式3 - var city = \"北京\": %s\n", city)
|
||
|
||
// 方式4: 短变量声明(最常用)
|
||
height := 175.5 // 自动推断为 float64 类型
|
||
fmt.Printf(" 方式4 - height := 175.5: %.1f\n", height)
|
||
|
||
// 注意:短变量声明只能在函数内部使用
|
||
// 在包级别必须使用 var 关键字
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateZeroValues 演示 Go 的零值概念
|
||
func demonstrateZeroValues() {
|
||
fmt.Println("2. 零值演示:")
|
||
fmt.Println(" Go 中每种类型都有默认的零值")
|
||
|
||
// 声明变量但不初始化,会自动赋予零值
|
||
var intVar int
|
||
var floatVar float64
|
||
var boolVar bool
|
||
var stringVar string
|
||
var pointerVar *int
|
||
|
||
fmt.Printf(" int 零值: %d\n", intVar) // 0
|
||
fmt.Printf(" float64 零值: %f\n", floatVar) // 0.000000
|
||
fmt.Printf(" bool 零值: %t\n", boolVar) // false
|
||
fmt.Printf(" string 零值: '%s'\n", stringVar) // ""(空字符串)
|
||
fmt.Printf(" pointer 零值: %v\n", pointerVar) // <nil>
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateTypeInference 演示类型推断
|
||
func demonstrateTypeInference() {
|
||
fmt.Println("3. 类型推断演示:")
|
||
|
||
// Go 可以根据赋值自动推断类型
|
||
var a = 42 // 推断为 int
|
||
var b = 3.14 // 推断为 float64
|
||
var c = "Hello" // 推断为 string
|
||
var d = true // 推断为 bool
|
||
|
||
// 使用 %T 可以打印变量的类型
|
||
fmt.Printf(" a = %v, 类型: %T\n", a, a)
|
||
fmt.Printf(" b = %v, 类型: %T\n", b, b)
|
||
fmt.Printf(" c = %v, 类型: %T\n", c, c)
|
||
fmt.Printf(" d = %v, 类型: %T\n", d, d)
|
||
|
||
// 短变量声明也支持类型推断
|
||
x := 100 // int
|
||
y := 2.5 // float64
|
||
z := 'A' // rune (int32)
|
||
|
||
fmt.Printf(" x := 100, 类型: %T\n", x)
|
||
fmt.Printf(" y := 2.5, 类型: %T\n", y)
|
||
fmt.Printf(" z := 'A', 类型: %T, 值: %d\n", z, z)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateMultipleDeclaration 演示多变量声明
|
||
func demonstrateMultipleDeclaration() {
|
||
fmt.Println("4. 多变量声明:")
|
||
|
||
// 方式1: 同时声明多个相同类型的变量
|
||
var x, y, z int = 1, 2, 3
|
||
fmt.Printf(" var x, y, z int = 1, 2, 3: %d, %d, %d\n", x, y, z)
|
||
|
||
// 方式2: 同时声明多个不同类型的变量
|
||
var name, age, height = "李四", 30, 180.0
|
||
fmt.Printf(" var name, age, height = ...: %s, %d, %.1f\n", name, age, height)
|
||
|
||
// 方式3: 使用短变量声明
|
||
a, b, c := "Go", 1.21, true
|
||
fmt.Printf(" a, b, c := ...: %s, %.2f, %t\n", a, b, c)
|
||
|
||
// 方式4: 使用括号组织多个变量声明
|
||
var (
|
||
firstName = "王"
|
||
lastName = "五"
|
||
fullName = firstName + lastName
|
||
)
|
||
fmt.Printf(" 组合声明: %s\n", fullName)
|
||
|
||
// 变量交换(Go 的特色功能)
|
||
m, n := 10, 20
|
||
fmt.Printf(" 交换前: m=%d, n=%d\n", m, n)
|
||
m, n = n, m // 交换变量值
|
||
fmt.Printf(" 交换后: m=%d, n=%d\n", m, n)
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateScope 演示变量作用域
|
||
func demonstrateScope() {
|
||
fmt.Println("5. 变量作用域:")
|
||
|
||
// 访问全局变量
|
||
fmt.Printf(" 全局变量: %s\n", globalVar)
|
||
fmt.Printf(" 包变量: %s, %s, %d\n", packageVar1, packageVar2, packageVar3)
|
||
|
||
// 函数级别变量
|
||
funcVar := "函数变量"
|
||
fmt.Printf(" 函数变量: %s\n", funcVar)
|
||
|
||
// 块级别作用域
|
||
if true {
|
||
blockVar := "块变量"
|
||
fmt.Printf(" 块变量(在 if 块内): %s\n", blockVar)
|
||
|
||
// 可以访问外层变量
|
||
fmt.Printf(" 在块内访问函数变量: %s\n", funcVar)
|
||
}
|
||
|
||
// blockVar 在这里无法访问,会编译错误
|
||
// fmt.Println(blockVar) // 这行会报错
|
||
|
||
// for 循环的作用域
|
||
for i := 0; i < 3; i++ {
|
||
loopVar := fmt.Sprintf("循环变量_%d", i)
|
||
fmt.Printf(" %s\n", loopVar)
|
||
}
|
||
// i 和 loopVar 在这里都无法访问
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
// demonstrateAssignment 演示变量赋值和修改
|
||
func demonstrateAssignment() {
|
||
fmt.Println("6. 变量赋值和修改:")
|
||
|
||
// 基本赋值
|
||
var score int = 85
|
||
fmt.Printf(" 初始分数: %d\n", score)
|
||
|
||
// 修改变量值
|
||
score = 90
|
||
fmt.Printf(" 修改后分数: %d\n", score)
|
||
|
||
// 复合赋值运算符
|
||
score += 5 // 等同于 score = score + 5
|
||
fmt.Printf(" score += 5: %d\n", score)
|
||
|
||
score -= 3 // 等同于 score = score - 3
|
||
fmt.Printf(" score -= 3: %d\n", score)
|
||
|
||
score *= 2 // 等同于 score = score * 2
|
||
fmt.Printf(" score *= 2: %d\n", score)
|
||
|
||
score /= 4 // 等同于 score = score / 4
|
||
fmt.Printf(" score /= 4: %d\n", score)
|
||
|
||
score %= 10 // 等同于 score = score % 10
|
||
fmt.Printf(" score %%= 10: %d\n", score)
|
||
|
||
// 自增和自减运算符
|
||
fmt.Printf(" score++ 前: %d\n", score)
|
||
score++ // 等同于 score = score + 1
|
||
fmt.Printf(" score++ 后: %d\n", score)
|
||
|
||
score-- // 等同于 score = score - 1
|
||
fmt.Printf(" score-- 后: %d\n", score)
|
||
|
||
// 注意:Go 中的 ++ 和 -- 是语句,不是表达式
|
||
// 不能写成 x = score++ 这样的形式
|
||
|
||
fmt.Println()
|
||
}
|
||
|
||
/*
|
||
运行这个程序:
|
||
go run 02-variables.go
|
||
|
||
学习要点:
|
||
1. Go 有多种变量声明方式,短变量声明 := 最常用
|
||
2. Go 支持类型推断,可以自动确定变量类型
|
||
3. 每种类型都有零值,未初始化的变量会自动赋予零值
|
||
4. 变量有作用域限制,块内变量无法在块外访问
|
||
5. Go 支持多变量同时声明和赋值
|
||
6. 复合赋值运算符可以简化代码
|
||
7. ++ 和 -- 在 Go 中是语句,不是表达式
|
||
|
||
常见错误:
|
||
1. 在包级别使用短变量声明 := (只能在函数内使用)
|
||
2. 访问超出作用域的变量
|
||
3. 将 ++ 或 -- 当作表达式使用
|
||
4. 忘记变量的零值概念
|
||
*/ |