2

Go 中如何使用结构体标签

 2 years ago
source link: https://www.techug.com/post/how-to-use-structure-labels-in-go.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.


img16351362081255953274.jpeg

译者:baiyutang

原文:https://www.digitalocean.com/community/tutorials/how-to-use-struct-tags-in-go

结构体,被用于搜集多个信息片段到一起集合到一个单元。这些信息集合被用于描述较高层级概念,如 Address,由 StreetCityStatePostalCode 组成。当你从数据库、API 等系统中读取信息时,你可以使用结构体标签控制信息如何给一个结构体的字段赋值。结构体标签是附着在一个结构体字段上的小块元数据,给使用结构体的 Go 代码提供指令。

结构体标签看起来是什么

结构体标签是出现在 Go 结构体类型声明后面的注释,每个标签由短字符关联相应的值组成。

一个结构体标签看起来如下,标签偏移带有反引号 ` 符号。

type User struct {
    Name string `example:"name"`
}

然后,其他 Go 代码能够检查这些结构并提取分配给它请求的特定键的值。如果没有其他代码检查,结构标签对代码的操作没有影响。

试试这个例子,看看结构体标签是什么样子的,如果没有来自另一个包的代码,它们将没有效果。

package main


import "fmt"


type User struct {
    Name string `example:"name"`
}


func (u *User) String() string {
    return fmt.Sprintf("Hi! My name is %s", u.Name)
}


func main() {
    u := &User{
        Name: "Sammy",
    }


    fmt.Println(u)
}
Output
Hi! My name is Sammy

JSON 编码

JavaScript Object Notation (JSON) 是一种文本格式,用于编码以不同字符串键组织的数据集合。它通常用于不同程序之间的数据通信,因为这种格式非常简单,存在许多库可以用许多不同的语言解码它。下面是 JSON 的一个例子:

{
  "language": "Go",
  "mascot": "Gopher"
}

 试试这个例子,看看 JSON 是如何在没有结构体标签的情况下编码的:

package main


import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"
)


type User struct {
    Name          string
    Password      string
    PreferredFish []string
    CreatedAt     time.Time
}


func main() {
    u := &User{
        Name:      "Sammy the Shark",
        Password:  "fisharegreat",
        CreatedAt: time.Now(),
    }


    out, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }


    fmt.Println(string(out))
}

这会打印如下输出

{
  "Name": "Sammy the Shark",
  "Password": "fisharegreat",
  "CreatedAt": "2019-09-23T15:50:01.203059-04:00"
}
package main


import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"
)


type User struct {
    name          string
    password      string
    preferredFish []string
    createdAt     time.Time
}


func main() {
    u := &User{
        name:      "Sammy the Shark",
        password:  "fisharegreat",
        createdAt: time.Now(),
    }


    out, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }


    fmt.Println(string(out))
}

使用结构体标签控制编码

package main


import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"
)


type User struct {
    Name          string    `json:"name"`
    Password      string    `json:"password"`
    PreferredFish []string  `json:"preferredFish"`
    CreatedAt     time.Time `json:"createdAt"`
}


func main() {
    u := &User{
        Name:      "Sammy the Shark",
        Password:  "fisharegreat",
        CreatedAt: time.Now(),
    }


    out, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }


    fmt.Println(string(out))
}
{
  "name": "Sammy the Shark",
  "password": "fisharegreat",
  "preferredFish": null,
  "createdAt": "2019-09-23T18:16:17.57739-04:00"
}

移出结构体空字段

package main


import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"
)


type User struct {
    Name          string    `json:"name"`
    Password      string    `json:"password"`
    PreferredFish []string  `json:"preferredFish,omitempty"`
    CreatedAt     time.Time `json:"createdAt"`
}


func main() {
    u := &User{
        Name:      "Sammy the Shark",
        Password:  "fisharegreat",
        CreatedAt: time.Now(),
    }


    out, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }


    fmt.Println(string(out))
}

这个例子将输出

{
  "name": "Sammy the Shark",
  "password": "fisharegreat",
  "createdAt": "2019-09-23T18:21:53.863846-04:00"
}

忽略私有字段

package main


import (
    "encoding/json"
    "fmt"
    "log"
    "os"
    "time"
)


type User struct {
    Name      string    `json:"name"`
    Password  string    `json:"-"`
    CreatedAt time.Time `json:"createdAt"`
}


func main() {
    u := &User{
        Name:      "Sammy the Shark",
        Password:  "fisharegreat",
        CreatedAt: time.Now(),
    }


    out, err := json.MarshalIndent(u, "", "  ")
    if err != nil {
        log.Println(err)
        os.Exit(1)
    }


    fmt.Println(string(out))
}

当你运营这个例子,你将看到这个输出:

{
  "name": "Sammy the Shark",
  "createdAt": "2019-09-23T16:08:21.124481-04:00"
}

结构体标签提供一种强大的方法,增大结构体作用的代码功能。很多标准库和第三方库通过结构体标签来提供方式定制操作。在代码中有效地使用它们不仅提供了这种定制行为,还简洁地记录了将来的开发人员如何使用这些字段。

本文文字及图片出自 InfoQ


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK