Go types.SizesFor 怎样按目标架构计算类型尺寸
做 Go 源码分析、静态检查或代码生成时,如果要回答“这个类型在 amd64 还是 arm64 下占多少字节”,不要把当前机器的运行时结果当成通用答案。正确做法是把 compiler 和 arch 交给 types.SizesFor,拿到对应的 types.Sizes,再调用 Alignof、Offsetsof 和 Sizeof。未知的编译器与架构组合会返回 nil,应先处理这个边界。
官方文档地址:https://pkg.go.dev/go/types#SizesFor
SizesFor选择的是编译器和目标架构的布局模型,不是当前进程中的对象地址。compiler与arch必须一起记录;只改报告文字而不重新计算,会得到自相矛盾的数据。Offsetsof负责字段偏移,Alignof负责对齐,Sizeof负责类型总大小。- 布局报告应保留架构元数据,并把未知组合、负结果和 padding 当作边界信息处理。
先理解 SizesFor 的返回值与目标环境
types.SizesFor(compiler, arch) 返回一个实现了 types.Sizes 的布局计算器。官方文档说明,结果来自指定编译器对指定架构的尺寸规则;如果组合未知,返回值就是 nil。当前 gc 支持的架构包含 386、amd64、arm64、riscv64、wasm 等。
这里的 arch 不是 GOOS,也不是一台机器的实时探测结果。比如报告目标是 Linux arm64 时,尺寸选择仍然应表达为编译器与架构的布局组合;操作系统、交叉编译环境和报告元数据可以另行保存。图1只表达这些静态边界,不是运行截图。

用 compiler 和 arch 获取可用的 types.Sizes
把选择逻辑收口成一个函数,调用方就不会在不同模块里散落字符串。最重要的是保留 nil 检查:未知组合不应继续调用尺寸方法,也不应静默回退到当前机器。
package main
import (
"fmt"
"go/types"
)
func sizesForTarget(compiler, arch string) (types.Sizes, error) {
sizes := types.SizesFor(compiler, arch)
if sizes == nil {
// 未知组合不能生成看似正常的布局数字。
return nil, fmt.Errorf("unknown layout model: %s/%s", compiler, arch)
}
return sizes, nil
}
如果工具需要支持多个目标,建议把 compiler、arch 放进报告结构,而不是只保存一个 sizes 接口。这样同一份源码在 amd64 和 arm64 上重算时,差异能被识别为目标环境变化。
按声明顺序准备类型和字段
types.Sizes 的方法接收 types.Type 或字段变量切片。源码分析器通常已有 *types.Struct;通过 Field(i) 按声明顺序取出字段,再交给 Offsetsof,不要为了方便改成 map。字段顺序一旦丢失,偏移报告也就失去意义。
type FieldLayout struct {
// 保存名称和类型,避免报告只剩一串不可解释的数字。
Name string
Type string
Offset int64
}
func fieldLayouts(st *types.Struct, sizes types.Sizes) []FieldLayout {
fields := make([]*types.Var, st.NumFields())
for i := 0; i
示例把字段名和类型一并保存,便于后续输出 JSON、表格或编辑器提示。Offsetsof 的负值表示布局结果过大,不能当成有效偏移;生产工具应把它转成明确错误。
组合 Alignof、Offsetsof 和 Sizeof 形成报告
只记录字段偏移仍然不完整。Alignof 说明类型整体的对齐要求,Sizeof 给出类型占用的总大小;二者和字段偏移一起,才能解释字段之间的 padding,以及结构体作为数组元素时的步长边界。
type LayoutReport struct {
// 这两个字段决定报告数字适用的目标环境。
Compiler string
Arch string
Align int64
Size int64
Fields []FieldLayout
}
func makeReport(st *types.Struct, compiler, arch string) (LayoutReport, error) {
sizes, err := sizesForTarget(compiler, arch)
if err != nil {
// 不输出半份报告,调用方可把错误交给命令行或 CI。
return LayoutReport{}, err
}
return LayoutReport{
Compiler: compiler,
Arch: arch,
Align: sizes.Alignof(st),
Size: sizes.Sizeof(st),
Fields: fieldLayouts(st, sizes),
}, nil
}

StdSizes 的官方说明还给出了常见模型的假设:字符串和接口按两个 word 计算,切片按三个 word 计算,结构体大小取最后字段结束位置并结合对齐规则处理。这里的数字属于布局模型,不应写成所有编译器、架构和版本都完全相同。
跨架构比较时保留哪些边界
| 报告字段 | 回答的问题 | 注意事项 |
|---|---|---|
compiler/arch | 这组数字适用于谁 | 换目标就重新取得 Sizes |
Offsetsof | 字段从结构体起点的哪里开始 | 偏移差值可用来解释内部 padding |
Alignof | 整体需要怎样对齐 | 影响嵌套和数组元素边界 |
Sizeof | 类型总大小是多少 | 负值表示结果过大,不能当正常数据 |
不要把 types.Sizes 和 reflect.Type 混为一谈:前者适合尚未构造成运行时对象的源码类型模型,后者面向运行时 Go 类型。也不要把 Offsetsof 当成地址,它只是相对于结构体起点的布局信息。
常见问题
SizesFor 只传 arch 可以吗?
不可以。函数同时接收 compiler 和 arch;应把二者作为同一布局选择保存,未知组合先检查返回的 nil。
换成 arm64 只改报告里的字符串可以吗?
不可以。应重新调用 types.SizesFor("gc", "arm64"),并用新的 Sizes 重新计算字段偏移、对齐和总大小。
这能替代运行时反射吗?
不能简单替代。它解决的是源码类型与目标架构布局的静态报告;运行时对象、指针地址和反射场景仍应使用相应的运行时 API。
采用建议是:先固定报告的 compiler 与 arch,再用同一份 types.Sizes 完成所有字段和类型计算,最后把 nil、负结果、padding 和架构差异写进输出。这样生成的尺寸才有可解释的适用边界。
Go 自建类型检查器怎样复用解析阶段的 FileSet
- 上一篇
- Go 自建类型检查器怎样复用解析阶段的 FileSet
- 下一篇
- Go 修改 AST 后为什么不能把旧 Info 当成新的检查结果
-
- Golang · Go教程 | 28分钟前 | Go types.Sizes Alignof 字段对齐
- Go types.Sizes.Alignof 怎样解释字段对齐要求
- 241浏览 收藏
-
- Golang · Go教程 | 34分钟前 | Go 类型检查 FileSet types.NewChecker
- Go 自建类型检查器怎样复用解析阶段的 FileSet
- 228浏览 收藏
-
- Golang · Go教程 | 37分钟前 |
- Go types.Config.Error 怎样收集多个类型错误而非只保留首条
- 149浏览 收藏
-
- Golang · Go教程 | 44分钟前 | Go 类型检查 ast go/types Checker.Files
- Go types.Checker.Files 怎样检查同一包的多个 AST 文件
- 464浏览 收藏
-
- Golang · Go教程 | 49分钟前 |
- Go types.Term.Tilde 怎样保留约束中的近似类型标记
- 262浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go TypeParam.Index 怎样恢复签名中的参数顺序
- 248浏览 收藏
-
- Golang · Go教程 | 1小时前 | 泛型 · Go教程 · 类型系统 · Go go/types 泛型约束 types.NewTypeParam types.TypeParam SetConstraint
- Go types.NewTypeParam 怎样给类型参数绑定约束
- 372浏览 收藏
-
- Golang · Go教程 | 1小时前 |
- Go types.Named.TypeArgs 怎样导出实例化后的类型实参
- 243浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 967次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 973次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1081次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1059次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 896次使用
-
- Java 性能优化上线清单:从定位、改造到灰度发布
- 2026-06-11 860浏览
-
- Spring Boot 压测验证:Gatling、JMeter 与性能回归门禁
- 2026-06-11 843浏览
-
- Java NMT 非堆内存排查:Direct Buffer、线程栈与 Metaspace 分析
- 2026-06-11 826浏览
-
- Spring Boot 容器内存优化:JVM 堆、非堆与 MaxRAMPercentage
- 2026-06-11 809浏览
-
- Tomcat 连接与线程参数调优:maxThreads、acceptCount 与 KeepAlive
- 2026-06-11 792浏览

