You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Golang读取Go文件并解析其中struct属性?

实现方案

不要自己写正则匹配源码,Go标准库自带的AST解析工具链可以100%准确解析Go语法,不会被注释、换行、多字段同声明等特殊写法干扰,核心用到go/ast、go/parser、go/token三个标准包。

前置示例

假设待解析的car.go内容如下:

// car.go
package model

type Car struct {
	Brand string `json:"brand"`
	Price float64 `json:"price"`
	Year  int     `json:"year"`
	IsEV  bool    `json:"is_ev"`
}

实现代码

核心逻辑分四步:

  • 创建用于记录源码位置信息的文件集
  • 解析目标Go文件生成AST语法树
  • 遍历AST节点找到名为Car的结构体声明
  • 遍历结构体的字段列表,提取所有属性的名称、类型、标签信息

完整可运行代码:

package main

import (
	"fmt"
	"go/ast"
	"go/parser"
	"go/token"
	"os"
)

// StructField 存储提取到的结构体属性信息
type StructField struct {
	FieldName string
	FieldType string
	Tag       string
}

func main() {
	targetFile := "./car.go"
	fset := token.NewFileSet()
	// 解析源码文件,保留注释信息
	f, err := parser.ParseFile(fset, targetFile, nil, parser.ParseComments)
	if err != nil {
		fmt.Printf("解析文件失败: %v\n", err)
		os.Exit(1)
	}

	var carFields []StructField
	// 遍历所有顶层声明
	for _, decl := range f.Decls {
		genDecl, ok := decl.(*ast.GenDecl)
		if !ok {
			continue
		}
		// 遍历声明下的所有规格项
		for _, spec := range genDecl.Specs {
			typeSpec, ok := spec.(*ast.TypeSpec)
			if !ok {
				continue
			}
			// 匹配名为Car的类型
			if typeSpec.Name.Name != "Car" {
				continue
			}
			// 校验是否为结构体类型
			structType, ok := typeSpec.Type.(*ast.StructType)
			if !ok {
				fmt.Println("Car标识符不是结构体类型")
				os.Exit(1)
			}
			// 遍历所有结构体字段
			for _, field := range structType.Fields.List {
				// 处理同一声明下的多个同类型字段,比如 Brand,Alias string 这种写法
				for _, name := range field.Names {
					sf := StructField{
						FieldName: name.Name,
						FieldType: fmt.Sprint(field.Type),
					}
					// 提取字段标签,去掉两侧反引号
					if field.Tag != nil {
						sf.Tag = field.Tag.Value[1 : len(field.Tag.Value)-1]
					}
					carFields = append(carFields, sf)
				}
			}
		}
	}

	// 输出提取结果
	fmt.Printf("Car结构体共提取到%d个属性:\n", len(carFields))
	for _, field := range carFields {
		fmt.Printf("- 字段名: %s | 类型: %s | 标签: %s\n", field.FieldName, field.FieldType, field.Tag)
	}
}

运行结果

执行上述代码会输出:

Car结构体共提取到4个属性:
- 字段名: Brand | 类型: string | 标签: json:"brand"
- 字段名: Price | 类型: float64 | 标签: json:"price"
- 字段名: Year | 类型: int | 标签: json:"year"
- 字段名: IsEV | 类型: bool | 标签: json:"is_ev"

注意事项

  • 禁止用正则解析Go源码:Go语法存在大量特殊写法(多行字段、字段间穿插注释、同类型多字段合并声明、嵌套结构体等),正则匹配的漏判、错判率极高,标准库AST解析完全遵循Go语法规范,稳定性有保障。
  • 如果目标结构体定义在函数内部而非顶层,需要额外遍历函数体的AST节点做匹配,绝大多数业务场景下结构体都是顶层声明,上述代码可以直接覆盖。
  • 如果需要解析跨包引用的字段类型(比如字段是其他包导出的结构体类型),可以搭配go/packages包做全项目类型加载,简单提取字段名、基础类型、标签的场景下上述代码已经足够。

内容的提问来源于stack exchange,提问作者Luiz Felipe Limão

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 00:45:48