
go 语言允许在不同作用域中使用相同名称重新声明 const,这并非修改原有常量,而是通过作用域隔离实现的“遮蔽(shadowing)”,外层常量保持不变。
在 Go 中,const 声明具有词法作用域(lexical scope),其可见性严格受限于定义所在的作用域块(如函数、代码块 {} 内)。当在内层作用域(例如 main 函数内部)用相同标识符 s 声明一个新的 const 时,它并不会覆盖或修改包级(全局)作用域中已声明的 s,而只是暂时遮蔽(shadow)了外层变量——即在此作用域内,所有对 s 的引用均指向内层声明的版本。
以下示例清晰展示了这一机制:
package main
import "fmt"
const s string = "constant" // 包级常量,作用域为整个包
func main() {
const s = 0 // 函数级常量,类型由字面量推导为 int;遮蔽了外层 s
fmt.Println(s) // 输出: 0
}更进一步,嵌套作用域也能体现遮蔽的层级性:
package main
import "fmt"
func main() {
const a = 0 // 外层块常量(main 函数作用域)
fmt.Println(a) // → 0
{
const a = 1 // 内层块常量(匿名代码块),遮蔽外层 a
fmt.Println(a) // → 1
}
fmt.Println(a) // → 0(退出内层块后,外层 a 恢复可见)
}⚠️ 注意事项:
- 遮蔽仅发生在不同作用域之间;在同一作用域内重复声明同名 const 会触发编译错误:redeclared in this block。
- const 遮蔽与 var 遮蔽行为一致,但语义更安全——因为常量值不可变,遮蔽不会引发状态不一致问题。
- 尽管技术上可行,但过度使用同名遮蔽会降低代码可读性,建议通过有意义的命名(如 defaultTimeout, maxRetries)避免歧义。
✅ 总结:Go 中“重声明” const 实质是作用域内的遮蔽,而非值的变更。这是语言设计对封装性与灵活性的兼顾,开发者应善用作用域规则,而非将其视为“常量可变”的误解。










