激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Golang - golang如何使用struct的tag屬性的詳細(xì)介紹

golang如何使用struct的tag屬性的詳細(xì)介紹

2020-05-21 10:48Go語(yǔ)言中文網(wǎng) Golang

這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說(shuō)起,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

從一個(gè)例子說(shuō)起

我們經(jīng)常會(huì)碰到下面格式的struct定義:

?
1
2
3
4
type Person struct {
  Name string `json:"name"`
  Age int  `json:"age"`
}

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

當(dāng)golang的對(duì)象需要和json做轉(zhuǎn)換的時(shí)候,我們就經(jīng)常用到這個(gè)特性。

有兩點(diǎn)注意的地方:

1、如果一個(gè)域不是以大寫字母開頭的,那么轉(zhuǎn)換成json的時(shí)候,這個(gè)域是被忽略的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ cat main.go
package main
 
import (
  "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
$ ./main
value: {"name":"tom"}

我們看到轉(zhuǎn)換成json串之后,name正常輸出了,而age被丟棄了,因?yàn)閍ge以小寫字母開頭。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ cat main.go
package main
 
import (
  "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
$ ./main
value: {"Name":"tom","Age":12}

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

總結(jié)一下, json:"name" 格式串是用來(lái)指導(dǎo)json.Marshal/Unmarshal,在進(jìn)行json串和golang對(duì)象之間轉(zhuǎn)換的時(shí)候映射字段名使用的。再舉一個(gè)例子,json串和golang域名字可以任意轉(zhuǎn)換:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ cat main.go
 
package main
 
import (
  "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
$ ./main
value: {"age":"tom","address":12}

這個(gè)例子我們把Name映射成了 age,而把Age映射成address,當(dāng)然這是個(gè)奇葩的映射,沒(méi)有任何正向意義,只有負(fù)向意義,只是為了說(shuō)明可以進(jìn)行任何名字映射而已。

如果我們?nèi)タ磈son包的源代碼,我可以看到在encoding/json/encode.go, encoding/json/decode.go里面有讀取tag值得相關(guān)代碼。

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

也就是說(shuō)這個(gè)json的tag是被json.Marshal和json.Unmarshal來(lái)使用的。

我們?nèi)绾问褂胻ag

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$ cat main.go
package main
 
import (
  "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添加了一個(gè)validate函數(shù),validate驗(yàn)證age是不是合理。

這個(gè)函數(shù)可以擴(kuò)展對(duì)任意struct的任意valid域進(jìn)行驗(yàn)證。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
$ cat main.go
package main
 
import (
  "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")
  }
}

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

看執(zhí)行結(jié)果:

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://studygolang.com/articles/16507

延伸 · 閱讀

精彩推薦
  • Golanggolang 通過(guò)ssh代理連接mysql的操作

    golang 通過(guò)ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過(guò)ssh代理連接mysql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    a165861639710342021-03-08
  • Golanggo日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    go日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號(hào)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,...

    helight2992020-05-14
  • GolangGolang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語(yǔ)言中標(biāo)識(shí)符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語(yǔ)言中標(biāo)識(shí)符允許由...

    4272021-11-24
  • Golanggo語(yǔ)言制作端口掃描器

    go語(yǔ)言制作端口掃描器

    本文給大家分享的是使用go語(yǔ)言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • GolangGolang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧...

    天易獨(dú)尊11682021-06-09
  • Golanggolang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說(shuō)起,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看...

    Go語(yǔ)言中文網(wǎng)11352020-05-21
主站蜘蛛池模板: lutube成人福利在线观看污 | 亚洲一区在线观看视频 | 毛片免费观看视频 | 欧美色性| 成人一级毛片 | 国产精品美女久久久久久不卡 | 看黄在线观看 | 国产精品视频海角社区88 | 国产成人在线一区二区 | 7777视频 | www.精品视频 | 中文字幕精品一二三四五六七八 | 91麻豆蜜桃一区二区三区 | 偷偷草网站 | 久久恋 | 成人午夜在线免费 | jizzjizz中国人少妇中文 | 国产精品免费一区二区 | 久久久久一本一区二区青青蜜月 | 91精品欧美一区二区三区 | 久久久久成人免费 | 在线a毛片免费视频观看 | www.狠狠操.com| 午夜在线观看视频网站 | 粉嫩粉嫩一区二区三区在线播放 | 久久久一区二区三区精品 | 久久久久久中文字幕 | 国产在线欧美日韩 | 久久3 | 午夜精品成人 | 男女一边摸一边做羞羞视频免费 | 精品国产一区二区三区免费 | 国产精品久久久免费 | 欧美日韩亚洲另类 | freexxx69性欧美hd | 午夜小视频免费观看 | 国产亚洲精品一区二区三区 | 国产一区二区三区精品在线观看 | av大全在线播放 | 好吊色欧美一区二区三区四区 | 色女人在线 |