菲菲恋 發表於 2025-12-31 09:15:17

Golang将接口文档字段转结构体的实践指南

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">问题提出</a></li><li><a href="#_label1">实现思路和代码</a></li><li><a href="#_label2">测试</a></li><li><a href="#_label3">小结</a></li></ul></div><p>本文给出一个从接口文档字段说明文字转换成golang结构体的方法。</p>
<p class="maodian"><a name="_label0"></a></p><h2>问题提出</h2>
<p>近期使用golang完成一个数据传输的工程的编写,难度不大,但接口较多,每个接口传输的字段都不少,最多的接口字段,有超过150个。这些字段在查询数据库和发送数据都用到&mdash;&mdash;只是部分字段名称不同,为方便起见,同一接口的数据统一用一个结构体传递&mdash;&mdash;golang支持不同类型的名称。手工一一拷贝比较耗时,于是写了个小代码进行转换。由于接口文档是word格式,可以直接拷贝表格内容到文本文件,再转换。</p>
<p class="maodian"><a name="_label1"></a></p><h2>实现思路和代码</h2>
<p>word文档里字段的说明是表格形式的,拷贝出来后变成了tab,为方便起见,需要兼容tab和空格两种形式。golang结构体支持不同类型的名称,具体来说,在结构体中使用<code>db</code>指定查询数据库的名称,使用<code>json</code>指定序列化的字段。</p>
<p>由于接口文档字段使用的类型与golang定义类型不同,如文档里类型为<code>Integer</code>,实际对应golang里的<code>int</code>,这些不同之处,单独列出判断即可。另外要提的是,golang结构体变量第一个字符必须大写,因此要处理这种情况。</p>
<p>如果接口文档的字段是对象类型,或者数据库字段名称和文档名称不同,则要手动修改,但所遇不多。总体上,一个接口的数据统一一种格式,多元一体,大大提高效率。</p>
<p>代码如下:</p>
<div class="jb51code"><pre class="brush:go;">type MyConvertStruct_t struct {
        Type1 string
        Type2 string
}

var arrType []MyConvertStruct_t = []MyConvertStruct_t{
        {"String", "string"},
        {"Integer", "int"},
        {"Long", "int"},
}

func makeComment(name string) (ret string) {

        ret = fmt.Sprintf("`json:\"%v\" db:\"%v\"`", name, name)

        return
}

func main() {
        filePath := "tmp.txt"
        csvbuf, err := com.ReadTabFile(filePath)
        if err != nil {
                fmt.Println("打开文件失败:", err)
                return
        }

        typeMap := make(mapstring)
        for _, item := range arrType {
                typeMap = item.Type2
        }

        fmt.Println("------------------------------")
        for _, row := range csvbuf {
                name := row
                name = strings.TrimSpace(name)
                myType := row
                if value, exists := typeMap]; exists {
                        myType = value
                }
                comment := makeComment(name)
                // name字段,第一个字符大写
                name = strings.Title(name)
                fmt.Printf("%v %v %v\n", name, myType, comment)
        }
}
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>测试</h2>
<p>输入文件<code>tmp.txt</code>内容如下:</p>
<div class="jb51code"><pre class="brush:plain;">id ID值        String        0
num           数字        Integer        0
etype        类型        Integer       0
timestamp        时间        String        0
mCode        号码        String        0
mName        姓名        String        0
age       XX        String        0
addr        地址        String        0
mac        MAC名称        String        0
remark        备注        String        0
</pre></div>
<p>注意,上述文件内容使用空格或tab键将不同内容分隔。执行程序后,在终端输出信息如下:</p>
<blockquote><p>------------------------------<br />Id string `json:&quot;id&quot; db:&quot;id&quot;`<br />Num int `json:&quot;num&quot; db:&quot;num&quot;`<br />Etype int `json:&quot;etype&quot; db:&quot;etype&quot;`<br />Timestamp string `json:&quot;timestamp&quot; db:&quot;timestamp&quot;`<br />MCode string `json:&quot;mCode&quot; db:&quot;mCode&quot;`<br />MName string `json:&quot;mName&quot; db:&quot;mName&quot;`<br />Age string `json:&quot;age&quot; db:&quot;age&quot;`<br />Addr string `json:&quot;addr&quot; db:&quot;addr&quot;`<br />Mac string `json:&quot;mac&quot; db:&quot;mac&quot;`<br />Remark string `json:&quot;remark&quot; db:&quot;remark&quot;`</p></blockquote>
<p class="maodian"><a name="_label3"></a></p><h2>小结</h2>
<p>从输出结果可以看到,变量名称首字符大写,也生成了<code>json</code>和<code>db</code>两种格式的字段。符合预期。</p>
頁: [1]
查看完整版本: Golang将接口文档字段转结构体的实践指南