0

0

Golang中const常量与变量的区别_编译期确定与运行时分配

P粉602998670

P粉602998670

发布时间:2026-02-27 12:29:37

|

989人浏览过

|

来源于php中文网

原创

go的const是编译期字面量,无内存地址,不可取址;仅支持基础类型;无类型常量依上下文推导类型,影响接口赋值与泛型匹配;编译器激进优化,但大字符串仍占二进制只读段。

golang中const常量与变量的区别_编译期确定与运行时分配

const 值在编译期就固定,不能取地址

Go 的 const 不是运行时变量,而是编译器直接替换的字面量。它没有内存地址,所以 &x 会报错 cannot take the address of x

常见错误现象:想把 const 当作指针传参、放进切片或 map 的地址位置、或者用 unsafe.Pointer 转换——全都不行。

  • const port = 8080 → 可以直接用于 http.ListenAndServe(":8080", nil),但 http.ListenAndServe(fmt.Sprintf(":%d", port), nil) 会多一次运行时计算(虽小但存在)
  • 如果需要地址(比如测试中传指针),必须先赋值给变量:var p = port,再用 &p
  • 字符串 const 是“无类型字面量”,可隐式转为 stringfmt.Stringer 等,但无法调用方法(没接收者)

const 类型推导规则影响接口赋值

未显式指定类型的 const(如 const x = 42)是“无类型常量”,在赋值或传参时按上下文推导类型;一旦指定类型(const x int = 42),就严格按该类型处理。

这直接影响能否赋给接口类型:

立即学习go语言免费学习笔记(深入)”;

Spell.tools
Spell.tools

高颜值AI内容营销创作工具

下载
  • const s = "hello" → 可赋给 io.Writer?不行,因为 s 是无类型字符串,而 io.Writer 需要具体类型实现(如 *bytes.Buffer
  • const s string = "hello" → 仍是 string 类型,依然不能直接赋给 io.Writerstring 没实现该接口)
  • 真正能进接口的是变量:比如 var b bytes.Buffer; fmt.Fprint(&b, s) —— 这里 &b 才是 io.Writer

const 不能用于 slice/map/channel/func 等复合类型

Go 规定 const 只能是基础字面量类型:布尔、数字、字符串、以及它们的别名。任何含运行时结构的类型都不允许。

典型误用场景:

  • const arr = []int{1,2,3} → 编译错误:invalid array literal in const declaration
  • const m = map[string]int{"a": 1} → 同样报错,map 必须用 make 或字面量在运行时构造
  • const fn = func() {} → 不合法,函数值是运行时对象,且类型含闭包信息,无法编译期确定
  • 替代方案:用 var + init() 或包级变量初始化,或封装为返回值的函数(如 func DefaultConfig() Config { ... }

const 在性能和二进制体积上的实际影响

编译器对 const 的优化很激进:只要不被反射或 unsafe 绕过,所有使用点都会内联为立即数,不占数据段空间,也不产生读内存指令。

但要注意边界情况:

  • 大字符串 const html = `...50KB HTML...` → 编译后仍会存入二进制只读段,不是“完全消失”;若仅需部分片段,建议拆成小 const 或用 embed.FS
  • 浮点 const pi = 3.14159265359 → Go 默认用 float64,但若上下文是 float32(如 math.Sin(float32(pi))),会先转 float64 再截断,可能引入微小误差
  • 跨包引用 const(如 pkg.AConst)→ 导入方编译时直接拷贝值,不依赖运行时链接,这也是 Go 常量“零成本抽象”的核心

最易被忽略的一点:const 的类型精度会影响泛型约束匹配。比如 type Number interface{ ~int | ~int64 },那么 const x = 42 可以传入,但 const x int32 = 42 就不行——类型必须落在约束范围内,而不是靠推导“大概像”。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

207

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

242

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

351

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

214

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

406

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

385

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

200

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

1151

2025.06.17

html5播放器怎么用
html5播放器怎么用

本合集全面介绍HTML5播放器的使用方法,涵盖基础语法、自定义控制、兼容性处理及实战示例。阅读专题下面的文章了解更多详细内容。

0

2026.02.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 5.6万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号