亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Golang > 正文

golang如何使用struct的tag屬性的詳細介紹

2020-04-01 18:50:52
字體:
來源:轉載
供稿:網友

從一個例子說起

我們經常會碰到下面格式的struct定義:

type Person struct {  Name string `json:"name"`  Age int  `json:"age"`}

這個struct定義一個叫做Person的類型,包含兩個域Name和Age;但是在域的后面有神奇的 json:"name" ,這個用來干什么用?這篇文章試圖來解釋這個問題。

當golang的對象需要和json做轉換的時候,我們就經常用到這個特性。

有兩點注意的地方:

1、如果一個域不是以大寫字母開頭的,那么轉換成json的時候,這個域是被忽略的。

$ cat main.gopackage mainimport (  "fmt"  "encoding/json")type Person struct {  Name string `json:"name"`  age int  `json:"age"`}func main() {  person := Person { "tom", 12 }  if b, err := json.Marshal(person); err != nil {    fmt.Printf("error: %s", err.Error())  } else {    fmt.Printf("value: %s", b)  }}$ go build -o main main.go $ ./mainvalue: {"name":"tom"}

我們看到轉換成json串之后,name正常輸出了,而age被丟棄了,因為age以小寫字母開頭。

2、如果沒有使用 json:"name" tag,那么輸出的json字段名和域名是一樣的。

$ cat main.gopackage mainimport (  "fmt"  "encoding/json")type Person struct {  Name string  Age int}func main() {  person := Person { "tom", 12 }  if b, err := json.Marshal(person); err != nil {    fmt.Printf("error: %s", err.Error())  } else {    fmt.Printf("value: %s", b)  }}$ go build -o main main.go $ ./mainvalue: {"Name":"tom","Age":12}

我們看到輸出的json串使用的是struct定義的字段名。

總結一下, json:"name" 格式串是用來指導json.Marshal/Unmarshal,在進行json串和golang對象之間轉換的時候映射字段名使用的。再舉一個例子,json串和golang域名字可以任意轉換:

$ cat main.gopackage mainimport (  "fmt"  "encoding/json")type Person struct {  Name string  `json:"age"`  Age int    `json:"address"`}func main() {  person := Person { "tom", 12 }  if b, err := json.Marshal(person); err != nil {    fmt.Printf("error: %s", err.Error())  } else {    fmt.Printf("value: %s", b)  }}$ go build -o main main.go $ ./mainvalue: {"age":"tom","address":12}

這個例子我們把Name映射成了 age,而把Age映射成address,當然這是個奇葩的映射,沒有任何正向意義,只有負向意義,只是為了說明可以進行任何名字映射而已。

如果我們去看json包的源代碼,我可以看到在encoding/json/encode.go, encoding/json/decode.go里面有讀取tag值得相關代碼。

tag := sf.Tag.Get("json")

也就是說這個json的tag是被json.Marshal和json.Unmarshal來使用的。

我們如何使用tag

還是以前的例子,Person有一個域Age,我們能不能限定Age的值在1-100之間,不至于太大,否則這個值沒有意義了。

$ cat main.gopackage mainimport (  "fmt"  "strings"  "strconv"  "reflect" _ "encoding/json")type Person struct {  Name string  `json:"name"`  Age int    `json:"age" valid:"1-100"`}func (p * Person) validation() bool {  v := reflect.ValueOf(*p)  tag := v.Type().Field(1).Tag.Get("valid")  val := v.Field(1).Interface().(int)  fmt.Printf("tag=%v, val=%v/n", tag, val)    result := strings.Split(tag, "-")  var min, max int  min, _ = strconv.Atoi(result[0])  max, _ = strconv.Atoi(result[1])  if val >= min && val <= max {    return true  } else {    return false  }}func main() {  person1 := Person { "tom", 12 }  if person1.validation() {    fmt.Printf("person 1: valid/n")  } else {    fmt.Printf("person 1: invalid/n")  }  person2 := Person { "tom", 250 }  if person2.validation() {    fmt.Printf("person 2 valid/n")  } else {    fmt.Printf("person 2 invalid/n")  }}

這么例子我們給Person添加了一個validate函數,validate驗證age是不是合理。

這個函數可以擴展對任意struct的任意valid域進行驗證。

$ cat main.gopackage mainimport (  "fmt"  "strings"  "strconv"  "reflect" _ "encoding/json")type Person struct {  Name string  `json:"name"`  Age int    `json:"age" valid:"1-100"`}type OtherStruct struct {  Age int    `valid:"20-300"`}func validateStruct(s interface{}) bool { v := reflect.ValueOf(s) for i := 0; i < v.NumField(); i++ {  fieldTag  := v.Type().Field(i).Tag.Get("valid")  fieldName  := v.Type().Field(i).Name  fieldType  := v.Field(i).Type()  fieldValue := v.Field(i).Interface()  if fieldTag == "" || fieldTag == "-" {    continue  }  if fieldName == "Age" && fieldType.String() == "int" {    val := fieldValue.(int)    tmp := strings.Split(fieldTag, "-")    var min, max int    min, _ = strconv.Atoi(tmp[0])    max, _ = strconv.Atoi(tmp[1])    if val >= min && val <= max {      return true    } else {      return false    }  } } return true}func main() {  person1 := Person { "tom", 12 }  if validateStruct(person1) {    fmt.Printf("person 1: valid/n")  } else {    fmt.Printf("person 1: invalid/n")  }  person2 := Person { "jerry", 250 }  if validateStruct(person2) {    fmt.Printf("person 2: valid/n")  } else {    fmt.Printf("person 2: invalid/n")  }  other1 := OtherStruct { 12 }  if validateStruct(other1) {    fmt.Printf("other 1: valid/n")  } else {    fmt.Printf("other 1: invalid/n")  }  other2 := OtherStruct { 250 }  if validateStruct(other2) {    fmt.Printf("other 2: valid/n")  } else {    fmt.Printf("other 2: invalid/n")  }}

在這個例子中我們定義了一個函數validateStruct,接受任意一個struct作為參數;validateStruct為驗證struct中所有定義的Age字段,如果字段名字是Age,字段類型是int,并且定義了valid tag,那么就會驗證這個valid是否有效。

看執行結果:

$ go build -o main main.go 
$ ./main
person 1: valid
person 2: invalid
other 1: invalid
other 2: valid

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美电影院免费观看| 国产欧美精品xxxx另类| 欧美精品中文字幕一区| 亚洲精品中文字幕女同| 精品久久香蕉国产线看观看gif| 日韩综合中文字幕| 亚洲性av在线| 亚洲影院色在线观看免费| 欧美黑人xxxx| 亚洲精品久久久久中文字幕二区| 国产精品美女久久久久av超清| 人妖精品videosex性欧美| 亚洲欧美国产日韩中文字幕| 国产69精品久久久久99| 日韩欧美一区二区在线| 91亚洲午夜在线| 色婷婷综合久久久久中文字幕1| 欧美性受xxx| 中文字幕亚洲无线码在线一区| 国产精品久久久久久五月尺| 欧美激情亚洲综合一区| 91国语精品自产拍在线观看性色| 在线看欧美日韩| 亚洲一区二区三区成人在线视频精品| 美女av一区二区三区| 成人免费福利视频| 国产精品永久免费观看| 精品久久在线播放| 亚洲免费视频一区二区| 在线看福利67194| 国产自产女人91一区在线观看| 亚洲精品国产欧美| 日韩av在线免费观看| 中文字幕久精品免费视频| 国产美女扒开尿口久久久| 欧美极品第一页| 91亚洲国产成人久久精品网站| 97在线视频国产| 日韩在线视频国产| 成人淫片在线看| 国产精品国语对白| 96精品久久久久中文字幕| 日韩网站免费观看高清| 欧美激情久久久久久| 97香蕉超级碰碰久久免费软件| 日韩风俗一区 二区| 日韩精品欧美国产精品忘忧草| 亚洲最大av网站| 久久香蕉精品香蕉| 清纯唯美亚洲综合| 欧美中文在线观看| 欧美大全免费观看电视剧大泉洋| 97不卡在线视频| 国产精品自产拍在线观| 日韩中文字幕在线免费观看| 亚洲欧美在线一区| 播播国产欧美激情| 欧美一级电影久久| 国产91ⅴ在线精品免费观看| 国产精品美女www爽爽爽视频| 俺去亚洲欧洲欧美日韩| 国产成人精品久久二区二区91| 欧美一区二区三区艳史| 中文国产成人精品| 日韩在线视频免费观看高清中文| 国产a∨精品一区二区三区不卡| 久久精品国产视频| 国产成人免费av电影| 国产91在线播放精品91| 欧美精品久久一区二区| 成人激情综合网| 亚洲第一国产精品| 久久久久久成人精品| 日韩欧美一区二区三区久久| 一二美女精品欧洲| 久久久久久久久久久亚洲| 国产综合色香蕉精品| 久久69精品久久久久久久电影好| 日韩中文综合网| 亚洲精品理论电影| 最新日韩中文字幕| 亚洲精选中文字幕| 亚洲免费福利视频| 97欧美精品一区二区三区| 在线a欧美视频| 久久手机免费视频| 精品久久久视频| 国产91在线高潮白浆在线观看| 一区二区三区视频免费在线观看| 国产精品成人久久久久| 九色精品免费永久在线| 97免费中文视频在线观看| 欧美激情精品久久久久久大尺度| 国产a∨精品一区二区三区不卡| 亚洲国产精品久久91精品| 欧美日韩国产影院| 日本精品va在线观看| 国产亚洲欧洲高清| 国产一区二区视频在线观看| 中文字幕自拍vr一区二区三区| 97久久久免费福利网址| 色噜噜狠狠狠综合曰曰曰| 亚洲aa在线观看| www欧美xxxx| 精品亚洲aⅴ在线观看| 欧美日本啪啪无遮挡网站| 久久久精品电影| 8050国产精品久久久久久| 欧美性xxxx| 韩国欧美亚洲国产| 亚洲在线第一页| 在线亚洲欧美视频| 2020欧美日韩在线视频| 日本19禁啪啪免费观看www| 精品国产一区二区三区久久| 亚洲第一免费播放区| 国产精品三级久久久久久电影| 中文字幕亚洲图片| 激情懂色av一区av二区av| 欧美视频二区36p| 国产精品国产三级国产aⅴ9色| 国产日韩欧美综合| 亚洲欧洲日产国码av系列天堂| 欧美电影免费播放| 久操成人在线视频| 国产精品第一视频| 国产成人av在线| 日韩av大片在线| 国产精品国产自产拍高清av水多| 日韩一区二区av| 日本91av在线播放| 日本高清视频一区| 久久久97精品| 亚洲的天堂在线中文字幕| 亚洲天堂免费在线| 亚洲精品久久久久中文字幕二区| 欧美大全免费观看电视剧大泉洋| 国产精品一二三在线| 成人久久一区二区| 亚洲欧美在线免费| 性夜试看影院91社区| 亚洲色图17p| 久久这里只有精品视频首页| 亚洲伦理中文字幕| 亚洲成年网站在线观看| 欧美国产日本在线| 成人亲热视频网站| 国产精品av电影| 欧美日韩在线视频观看| 久久91亚洲精品中文字幕奶水| 不卡在线观看电视剧完整版| 亚洲色图五月天| 91久久精品国产91久久| 高潮白浆女日韩av免费看| 午夜精品视频在线| 国产99视频精品免视看7| 丝袜亚洲欧美日韩综合| 久久中文精品视频| 中文在线资源观看视频网站免费不卡| 国产91精品久久久久久久| 国产精品成人观看视频国产奇米| 欧美电影免费观看| 欧美成人精品在线观看| 国产精品一区二区av影院萌芽|