302 lines
7.5 KiB
Go
302 lines
7.5 KiB
Go
/*
|
||
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 块中有效
|
||
*/ |