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

302 lines
7.5 KiB
Go
Raw Permalink 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.

/*
03-constants.go - Go 语言常量详解
学习目标:
1. 理解常量的概念和作用
2. 掌握常量声明的方式
3. 学会使用 iota 枚举器
4. 了解类型化和无类型化常量
5. 掌握常量表达式的计算
知识点:
- const 关键字
- 常量组声明
- iota 枚举器
- 类型化常量 vs 无类型化常量
- 常量表达式
- 预定义常量
*/
package main
import "fmt"
// 包级别常量声明
const PI = 3.14159
const COMPANY_NAME = "Go 学习公司"
// 常量组声明
const (
// 基本常量
MAX_SIZE = 100
MIN_SIZE = 1
// 使用表达式的常量
BUFFER_SIZE = MAX_SIZE * 2
// 字符串常量
VERSION = "1.0.0"
AUTHOR = "Go 学习者"
)
// 使用 iota 的枚举常量
const (
// iota 从 0 开始,每行递增 1
MONDAY = iota // 0
TUESDAY // 1
WEDNESDAY // 2
THURSDAY // 3
FRIDAY // 4
SATURDAY // 5
SUNDAY // 6
)
// 更复杂的 iota 用法
const (
_ = iota // 0使用 _ 忽略第一个值
KB = 1 << (10 * iota) // 1 << (10 * 1) = 1024
MB // 1 << (10 * 2) = 1048576
GB // 1 << (10 * 3) = 1073741824
TB // 1 << (10 * 4) = 1099511627776
)
// 类型化常量
const (
MAX_INT int = 2147483647
MAX_FLOAT float64 = 1.7976931348623157e+308
IS_ENABLED bool = true
)
func main() {
fmt.Println("=== Go 语言常量详解 ===\n")
// 演示基本常量使用
demonstrateBasicConstants()
// 演示 iota 枚举器
demonstrateIota()
// 演示常量表达式
demonstrateConstantExpressions()
// 演示类型化和无类型化常量
demonstrateTypedConstants()
// 演示常量的特性
demonstrateConstantProperties()
}
// demonstrateBasicConstants 演示基本常量使用
func demonstrateBasicConstants() {
fmt.Println("1. 基本常量使用:")
// 使用包级别常量
fmt.Printf(" 圆周率: %f\n", PI)
fmt.Printf(" 公司名称: %s\n", COMPANY_NAME)
fmt.Printf(" 最大尺寸: %d\n", MAX_SIZE)
fmt.Printf(" 缓冲区大小: %d\n", BUFFER_SIZE)
// 函数内部常量声明
const LOCAL_CONST = "这是局部常量"
fmt.Printf(" 局部常量: %s\n", LOCAL_CONST)
// 常量组声明(函数内部)
const (
RED = "红色"
GREEN = "绿色"
BLUE = "蓝色"
)
fmt.Printf(" 颜色常量: %s, %s, %s\n", RED, GREEN, BLUE)
fmt.Println()
}
// demonstrateIota 演示 iota 枚举器
func demonstrateIota() {
fmt.Println("2. iota 枚举器:")
// 基本 iota 用法
fmt.Printf(" 星期枚举:\n")
fmt.Printf(" MONDAY: %d\n", MONDAY)
fmt.Printf(" TUESDAY: %d\n", TUESDAY)
fmt.Printf(" WEDNESDAY: %d\n", WEDNESDAY)
fmt.Printf(" THURSDAY: %d\n", THURSDAY)
fmt.Printf(" FRIDAY: %d\n", FRIDAY)
fmt.Printf(" SATURDAY: %d\n", SATURDAY)
fmt.Printf(" SUNDAY: %d\n", SUNDAY)
// 存储单位枚举
fmt.Printf(" 存储单位:\n")
fmt.Printf(" KB: %d 字节\n", KB)
fmt.Printf(" MB: %d 字节\n", MB)
fmt.Printf(" GB: %d 字节\n", GB)
fmt.Printf(" TB: %d 字节\n", TB)
// 更多 iota 示例
const (
A = iota * 2 // 0 * 2 = 0
B // 1 * 2 = 2
C // 2 * 2 = 4
D // 3 * 2 = 6
)
fmt.Printf(" iota 表达式: A=%d, B=%d, C=%d, D=%d\n", A, B, C, D)
// 跳过某些值
const (
E = iota + 1 // 0 + 1 = 1
F // 1 + 1 = 2
_ // 2 + 1 = 3 (跳过)
G // 3 + 1 = 4
)
fmt.Printf(" 跳过值: E=%d, F=%d, G=%d\n", E, F, G)
fmt.Println()
}
// demonstrateConstantExpressions 演示常量表达式
func demonstrateConstantExpressions() {
fmt.Println("3. 常量表达式:")
// 算术表达式
const (
A = 10
B = 20
SUM = A + B
PRODUCT = A * B
QUOTIENT = B / A
)
fmt.Printf(" 算术表达式:\n")
fmt.Printf(" A + B = %d\n", SUM)
fmt.Printf(" A * B = %d\n", PRODUCT)
fmt.Printf(" B / A = %d\n", QUOTIENT)
// 字符串表达式
const (
FIRST_NAME = "张"
LAST_NAME = "三"
FULL_NAME = FIRST_NAME + LAST_NAME
)
fmt.Printf(" 字符串表达式: %s\n", FULL_NAME)
// 布尔表达式
const (
X = 5
Y = 10
IS_GREATER = X > Y
IS_EQUAL = X == Y
)
fmt.Printf(" 布尔表达式:\n")
fmt.Printf(" %d > %d = %t\n", X, Y, IS_GREATER)
fmt.Printf(" %d == %d = %t\n", X, Y, IS_EQUAL)
fmt.Println()
}
// demonstrateTypedConstants 演示类型化和无类型化常量
func demonstrateTypedConstants() {
fmt.Println("4. 类型化和无类型化常量:")
// 无类型化常量(更灵活)
const UNTYPED_INT = 42
const UNTYPED_FLOAT = 3.14
const UNTYPED_STRING = "Hello"
// 类型化常量(类型固定)
const TYPED_INT int = 42
const TYPED_FLOAT float64 = 3.14
const TYPED_STRING string = "Hello"
fmt.Printf(" 无类型化常量:\n")
fmt.Printf(" UNTYPED_INT 可以赋值给不同的数值类型\n")
var i8 int8 = UNTYPED_INT // 可以
var i16 int16 = UNTYPED_INT // 可以
var i32 int32 = UNTYPED_INT // 可以
var i64 int64 = UNTYPED_INT // 可以
fmt.Printf(" int8: %d, int16: %d, int32: %d, int64: %d\n", i8, i16, i32, i64)
fmt.Printf(" 类型化常量:\n")
fmt.Printf(" TYPED_INT 只能赋值给相同类型\n")
var typedVar int = TYPED_INT // 可以,类型匹配
// var typedVar2 int32 = TYPED_INT // 编译错误,类型不匹配
fmt.Printf(" typedVar: %d\n", typedVar)
// 演示无类型化常量的精度
const HUGE = 1e1000 // 无类型化常量可以有很高的精度
fmt.Printf(" 高精度常量: 可以定义超出普通类型范围的常量\n")
fmt.Println()
}
// demonstrateConstantProperties 演示常量的特性
func demonstrateConstantProperties() {
fmt.Println("5. 常量的特性:")
// 常量在编译时确定
const COMPILE_TIME = 100 + 200
fmt.Printf(" 编译时计算: %d\n", COMPILE_TIME)
// 常量不能修改
const IMMUTABLE = "不可变"
fmt.Printf(" 不可变性: %s\n", IMMUTABLE)
// IMMUTABLE = "尝试修改" // 编译错误
// 常量可以用于数组长度
const ARRAY_SIZE = 5
var arr [ARRAY_SIZE]int
fmt.Printf(" 用作数组长度: 数组长度为 %d\n", len(arr))
// 预定义常量
fmt.Printf(" 预定义常量:\n")
fmt.Printf(" true: %t\n", true)
fmt.Printf(" false: %t\n", false)
// 常量的作用域
fmt.Printf(" 常量作用域:\n")
fmt.Printf(" 包级别常量在整个包中可见\n")
fmt.Printf(" 函数级别常量只在函数内可见\n")
// 在块作用域中定义常量
if true {
const BLOCK_CONST = "块常量"
fmt.Printf(" 块常量: %s\n", BLOCK_CONST)
}
// BLOCK_CONST 在这里不可访问
fmt.Println()
}
/*
运行这个程序:
go run 03-constants.go
学习要点:
1. 常量使用 const 关键字声明,一旦定义不能修改
2. 常量在编译时确定值,不能使用运行时才能确定的值
3. iota 是常量生成器,在 const 块中从 0 开始递增
4. 无类型化常量比类型化常量更灵活,可以赋值给兼容的类型
5. 常量可以用于需要编译时常量的地方,如数组长度
6. 常量表达式在编译时计算,支持算术、字符串、布尔运算
7. 常量有作用域限制,和变量类似
常见用途:
1. 定义配置参数(如缓冲区大小、超时时间)
2. 定义枚举值(如状态码、错误码)
3. 定义数学常数(如 PI、E
4. 定义字符串常量(如版本号、默认值)
注意事项:
1. 常量值必须在编译时确定
2. 不能将函数调用结果赋值给常量
3. 不能将变量赋值给常量
4. iota 只在 const 块中有效
*/