Files
golang/golang-learning/01-basics/02-variables.go
2025-08-24 01:01:26 +08:00

258 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
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. 忘记变量的零值概念
*/