掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
通過(guò) reflect.Type 獲取結(jié)構(gòu)體成員信息 reflect.StructField 結(jié)構(gòu)中的 Tag 被稱為結(jié)構(gòu)體標(biāo)簽(Struct Tag)。結(jié)構(gòu)體標(biāo)簽是對(duì)結(jié)構(gòu)體字段的額外信息標(biāo)簽。

JSON、BSON 等格式進(jìn)行序列化及對(duì)象關(guān)系映射(Object Relational Mapping,簡(jiǎn)稱 ORM)系統(tǒng)都會(huì)用到結(jié)構(gòu)體標(biāo)簽,這些系統(tǒng)使用標(biāo)簽設(shè)定字段在處理時(shí)應(yīng)該具備的特殊屬性和可能發(fā)生的行為。這些信息都是靜態(tài)的,無(wú)須實(shí)例化結(jié)構(gòu)體,可以通過(guò)反射獲取到。
結(jié)構(gòu)體標(biāo)簽(Struct Tag)類似于 C# 中的特性(Attribute)。C# 允許在類、字段、方法等前面添加 Attribute,然后在反射系統(tǒng)中可以獲取到這個(gè)屬性系統(tǒng)。例如:
[Conditional("DEBUG")]
public static void Message(string msg)
{
Console.WriteLine(msg);
}
Tag 在結(jié)構(gòu)體字段后方書寫的格式如下:
`key1:"value1" key2:"value2"`
結(jié)構(gòu)體標(biāo)簽由一個(gè)或多個(gè)鍵值對(duì)組成。鍵與值使用冒號(hào)分隔,值用雙引號(hào)括起來(lái)。鍵值對(duì)之間使用一個(gè)空格分隔。
StructTag 擁有一些方法,可以進(jìn)行 Tag 信息的解析和提取,如下所示:
編寫 Tag 時(shí),必須嚴(yán)格遵守鍵值對(duì)的規(guī)則。結(jié)構(gòu)體標(biāo)簽的解析代碼的容錯(cuò)能力很差,一旦格式寫錯(cuò),編譯和運(yùn)行時(shí)都不會(huì)提示任何錯(cuò)誤,參見下面這個(gè)例子:
package main
import (
"fmt"
"reflect"
)
func main() {
type cat struct {
Name string
Type int `json: "type" id:"100"`
}
typeOfCat := reflect.TypeOf(cat{})
if catType, ok := typeOfCat.FieldByName("Type"); ok {
fmt.Println(catType.Tag.Get("json"))
}
}代碼輸出空字符串,并不會(huì)輸出期望的 type。
第 12 行中,在
json:和
"type"之間增加了一個(gè)空格。這種寫法沒有遵守結(jié)構(gòu)體標(biāo)簽的規(guī)則,因此無(wú)法通過(guò) Tag.Get 獲取到正確的 json 對(duì)應(yīng)的值。
這個(gè)錯(cuò)誤在開發(fā)中非常容易被疏忽,造成難以察覺的錯(cuò)誤。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流