咋一看标题, 这个有啥用?
你别说还真有用, 当你想重构你的项目的时候, 或者你想rpc调用其他语言时, 这个就不用你一个一个去编写message了,而是根据你的go结构体直接生成, 简洁高效(好吧, 一般人也不会有这种需求, 有也直接发给ai就行, 不过各位看官就当看个乐子, 学习下也可以)
实现原理
思路
随机读取包含go的结构体文件, 然后读取每个结构的内容, 以及结构体名字, 通过fmt.Sprintf嵌入到准备好的模板中, 生成新的可执行go文件, 这样就可以生成proto文件了
实现代码
定义proto结构体, 方便后续调用操作
// Proto 结构体用于生成 Protobuf 描述
type Proto struct {
}
// NewProto 创建一个新的 Proto 实例
func NewProto() *Proto {
return &Proto{
}
}
读取go 文件, 根据type 分割 go 结构体,
// readGoFile 读取 Go 文件并提取结构体定义
func (p *Proto) readGoFile(gopath string) ([]string, error) {
data, err := os.ReadFile(gopath)
if err != nil {
return nil, err
}
datas := strings.Split(strings.TrimSpace(string(data)), "type ")
for i := 1; i < len(datas); i++ {
datas[i] = "type " + datas[i]
}
return datas[1:], nil
}
将分割好的每个结构体依次获取它的结构体名字, 构建到GetStruct放法中, 并将其放到st中, 最后插入模板, 也就是template中, template在文章后面
func (p *Proto) writeGoFile(datas []string, outputGoPath string) error {
template := (放在文章后面)
st := make([]string, 0)
for i := 0; i < len(datas); i++