• struct


    概述

    Go的struct声明允许字段附带Tag来对字段做一些标记

    该Tag 不仅仅是一个字符,其主要的作用是用于反射场景, reflect包中提供了操作Tag 的方法,所以Tag的写法也要遵循一定的规则

    Tag的本质

    2.1 Tag规则

    Tag本身是一个字符串,但字符串中却是:以空格分隔的 key:value 对。

    • key: 必须是非空字符串,字符串不能包含控制字符,空格,引号, 冒号
    • value: 以双引号标记的字符串
    • 注意:冒号前后不能有空格

    如下代码所示,如此写没有实际意义,仅用于说明:

    type Server struct {
        ServerName string `key1: "value1" key11:"value11"`
        ServerIP   string `key2: "value2"`
    }
    

    上述代码ServerName字段的Tag包含两个key-value对。ServerIP字段的Tag只包含一个key-value对。

    2.2 Tag是Struct的一部分

    前面说过,Tag只有在反射场景中才有用,而反射包中提供了操作Tag的方法

    以下是reflect包中的类型声明,省略了部分与本文无关的字段。

    // A StructField describes a single field in a struct.
    type StructField struct {
        // Name is the field name.
        Name string
        ...
        Type      Type      // field type
        Tag       StructTag // field tag string
        ...
    }
    
    type StructTag string
    

    可见,描述一个结构体成员的结构中包含了StructTag,而其本身是一个string。也就是说Tag其实是结构体字段的一个组成部分。

    2.3 获取Tag

    StructTag提供了Get(key string) string方法来获取Tag,示例如下:

    package main
    
    import (
        "reflect"
        "fmt"
    )
    
    type Server struct {
        ServerName string `key1:"value1" key11:"value11"`
        ServerIP   string `key2:"value2"`
    }
    
    func main() {
        s := Server{}
        st := reflect.TypeOf(s)
    
        field1 := st.Field(0)
        fmt.Printf("key1:%v
    ", field1.Tag.Get("key1"))
        fmt.Printf("key11:%v
    ", field1.Tag.Get("key11"))
    
        filed2 := st.Field(1)
        fmt.Printf("key2:%v
    ", filed2.Tag.Get("key2"))
    }
    

    程序输出如下:

    key1:value1
    key11:value11
    key2:value2
    

    3. Tag存在的意义

    使用反射可以动态的给结构体成员赋值,正是因为有tag,在赋值前可以使用tag来决定赋值的动作。
    比如,官方的encoding/json包,可以将一个JSON数据Unmarshal进一个结构体,此过程中就使用了Tag。该包定义一些规则,只要参考该规则设置tag就可以将不同的JSON数据转换成结构体。

    总之:正是基于struct的tag特性,才有了诸如json、orm等等的应用。理解这个关系是至关重要的。可以定义另一种tag规则,来处理你特有的数据

    4.Tag常见用法

    常见的tag用法,主要是JSON数据解析、ORM映射等。

    【参考】

    ♥永远年轻,永远热泪盈眶♥
  • 相关阅读:
    Chrome浏览器设置默认编码
    linux上安装subversion
    详解Linux命令行下常用svn命令
    css 使容器宽度适应内容宽
    Windsor Spring
    T4 Generate POCO Class for MSSQ
    MSSQ 树型结构数据 循环操作
    System.Reflection.Emit 动态实现接口
    T4 SqlSugar MySql
    微信多开
  • 原文地址:https://www.cnblogs.com/failymao/p/14905965.html
Copyright © 2020-2023  润新知