结构体标签可以说是 golang 中一个比较有特殊的特性。在讲解 golang 结构体标签之前我们先来看一个结构体标签最常用的场景。有过 web 后端编程的经验的伙伴们应该都会有这样的感受,后端程序处理数据的流程可以抽象为:1、接受前端请求->处理请求->业务数据写入数据库;2、从数据库读取数据->处理业务->向前端返回数据

在这两个个过程中程序会有两次数据的转换:前端数据(json 数据或者 form 表单)与程序对象结构体的互转,数据库数据(比如 sql 数据)与程序的对象结构体的互转。

在这里插入图片描述

在 golang 中我们借助 struct tag,这些转换都会特别简单。我们来看一个例子:

package main

import (
	"encoding/json"
	"net/http"
)

// json:"param-1" 和 json:"param-2 即为结构体标签,其
// 要紧跟在结构体属性后面使用反引号 `` 引起来。
type data struct {
	Param1 string `json:"param-1"`
	Param2 int    `json:"param-2"`
}

func main() {
	http.HandleFunc("/getjson", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		reps, err := json.Marshal(data{Param1: "I am a string", Param2: 2})
		if err != nil {
			panic(err)
		}
		w.Write([]byte(reps))
	})
	http.ListenAndServe("0.0.0.0:18080", nil)
}
go run main.go
# curl -i http://127.0.0.1:18080/getjson
HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 30 Sep 2022 07:22:17 GMT
Content-Length: 39

{"param-1":"I am a string","param-2":2}

从上面的例子我们看到借助结构体标签我们能很容易的完成 golang 结构体到 json 数据的转换。除了 json 还有很多其他 golang 库可以完成 golang 结构体到其他数据的转换,如:xml、protocolbuf ;还能用于数据库 orm 相关 beego orm、gorm。

reflect.StructTag

reflect.StructTagreflect.StructTag

我们来看一个官方的例子:

package main

import (
	"fmt"
	"reflect"
)

func main() {
	type S struct {
		F string `species:"gopher" color:"blue"`
	}

	s := S{}
	st := reflect.TypeOf(s)
	field := st.Field(0)
	fmt.Println(field.Tag.Get("color"), field.Tag.Get("species"))

}

程序运行的输出结果:

blue gopher
reflect.StructTagGetLookup