当前位置:首页 > 文章列表 > Golang > Go教程 > Go types.SizesFor 怎样按目标架构计算类型尺寸

Go types.SizesFor 怎样按目标架构计算类型尺寸

来源:17golang原创 2026-11-10 15:47:26 0浏览 收藏

做 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.SizesFor 选择 types.Sizes 布局模型并产生报告指标的结构说明图
图1:结构说明图,展示目标环境如何对应到 types.Sizes 布局模型;这不是截图或运行证据。

用 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
}
types.Struct 字段与 types.Sizes 的 Offsetsof Alignof Sizeof 组成布局报告的静态关系图
图2:布局说明图,展示字段偏移、整体对齐和类型总大小如何落入跨架构报告;这不是运行证据。

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 和架构差异写进输出。这样生成的尺寸才有可解释的适用边界。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go 自建类型检查器怎样复用解析阶段的 FileSetGo 自建类型检查器怎样复用解析阶段的 FileSet
上一篇
Go 自建类型检查器怎样复用解析阶段的 FileSet
Go 修改 AST 后为什么不能把旧 Info 当成新的检查结果
下一篇
Go 修改 AST 后为什么不能把旧 Info 当成新的检查结果
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    967次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    973次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1081次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1059次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    896次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码