在 Go 中,有些东西不能定义为常量:
接口类型:Go 中的接口类型不能被定义为常量。接口是一种抽象类型,它描述了对象的行为,而不关心对象的具体类型。由于接口类型是动态的,无法在编译时确定其具体的值,因此不能作为常量。
go// 不能将接口类型定义为常量 const myInterface error = MyError{}函数类型:函数类型也不能定义为常量。函数类型是一种抽象的类型,描述了函数的签名和参数列表等信息,而不是具体的函数实现。因此,函数类型无法在编译时确定其值,不能作为常量。
go// 不能将函数类型定义为常量 const myFunc func(int) int = func(x int) int { return x + 1 }动态计算的值:常量必须在编译时期确定其值,不能依赖于运行时计算的结果。因此,任何需要在运行时才能确定值的表达式或函数调用都不能作为常量。注意
time.Second本身是一个类型为time.Duration的常量,用它定义常量是合法的;不合法的是调用运行时才能求值的函数。go// 不能将动态计算的表达式定义为常量 const maxFileSize = 1024 * 1024 // OK,编译时可确定 const timeout = time.Second // OK,time.Second 本身是常量 const now = time.Now() // 不能,time.Now() 是运行时的函数调用切片、映射等引用类型的值:常量的类型只能是基本类型(布尔、数值、字符串)。切片、映射、结构体等需要运行时构造的复合值不能定义为常量。
go// 不能将切片或映射定义为常量 const mySlice = []int{1, 2, 3} // 不能,切片不是常量类型 const myMap = map[string]int{"a": 1} // 不能对常量取地址:常量是编译期的值,不一定占用运行时内存,因此不能对常量取地址。
goconst count = 10 p := &count // 不能,invalid operation: cannot take address of count
这些限制指向同一件事:常量的值必须在编译期确定,不能依赖运行时上下文或动态计算。