Go的struct
1. 前言
Go的struct声明允许字段附带Tag来对字段做一些标记。
该Tag不仅仅是一个字符串那么简单,因为其主要用于反射场景,reflect包中提供了操作Tag的方法,所以Tag写法也要遵循一定的规则。
2. Tag的本质
2.1 Tag规则
Tag本身是一个字符串,但字符串中却是:以空格分隔的 key:value 对。
key: 必须是非空字符串,字符串不能包含控制字符、空格、引号、冒号。value: 以双引号标记的字符串- 注意:冒号前后不能有空格
如下代码所示,如此写没有实际意义,仅用于说明Tag规则
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的方法。在说方法前,有必要先了解一下Go是如何管理struct字段的。
以下是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\n", field1.Tag.Get("key1"))
fmt.Printf("key11:%v\n", field1.Tag.Get("key11"))
filed2 := st.Field(1)
fmt.Printf("key2:%v\n", filed2.Tag.Get("key2"))
}
程序输出如下:
key1:value1
key11:value11
key2:value2
3. Tag存在的意义
本文示例中tag没有任何实际意义,这是为了阐述tag的定义与操作方法,也为了避免与你之前见过的诸如json:xxx混淆。
使用反射可以动态的给结构体成员赋值,正是因为有tag,在赋值前可以使用tag来决定赋值的动作。
比如,官方的encoding/json包,可以将一个JSON数据Unmarshal进一个结构体,此过程中就使用了Tag. 该包定义一些规则,只要参考该规则设置tag就可以将不同的JSON数据转换成结构体。
总之:正是基于struct的tag特性,才有了诸如json、orm等等的应用。理解这个关系是至关重要的。或许,你可以定义另一种tag规则,来处理你特有的数据。
4. Tag常见用法
常见的tag用法,主要是JSON数据解析、ORM映射等。====
Go的struct的更多相关文章
- 使用struct处理二进制
有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...
- golang struct扩展函数参数命名警告
今天在使用VSCode编写golang代码时,定义一个struct,扩展几个方法,如下: package storage import ( "fmt" "github.c ...
- go-使用 unsafe 修改 struct 中的 field 的值
以下是方法,不要纠结原理,等东西积累多了,你才有能力纠结原理: 首先,你需要有一个这样的函数,这是在 nsq 的源码里直接抄过来的: func unsafeValueOf(val reflect.Va ...
- C语言中struct位域的定义和使用
位域的定义和使用 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可.为了节省存储空间,并使处理简便,C语言又 ...
- C# Struct结构体里数组长度的指定
typedef struct Point{ unsigned short x; unsigned short y; }mPoint;//点坐标 typedef struct Line{ mPoint ...
- C 语言Struct 实现运行类型识别 RTTI
通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型. (2)dynamic_cast: ...
- VC++ : error LNK2001: unresolved external symbol "__declspec(dllimport) public: __thiscall std::basic_string<wchar_t,struct std::char_traits<wchar_t>
最近学习Google Breakpad,将其用在了自己的项目中,编译的版本为VS2010,没有什么问题.但是为了和之前的程序兼容,需要使用VS2008版本的程序,于是又编译了VS2008版本的代码,但 ...
- 字节流与数据类型的相互转换---使用struct模块
字节流与数据类型的相互转换---使用struct模块 http://blog.csdn.net/Sunboy_2050/article/details/5974029 Python是一门非常简洁的语言 ...
- 窥探Swift之别具一格的Struct和Class
说到结构体和类,还是那句话,只要是接触过编程的小伙伴们对这两者并不陌生.但在Swift中的Struct和Class也有着令人眼前一亮的特性.Struct的功能变得更为强大,Class变的更为灵活.St ...
- struct 大小计算
结构体是一种复合数据类型,通常编译器会自动的进行其成员变量的对齐,已提高数据存取的效率.在默认情况下,编译器为结构体的成员按照自然对齐(natural alignment)条方式分配存储空间,各个成员 ...
随机推荐
- Bootstrap 学习笔记13 附加导航插件
附加导航代码: <style> a:focus { outline: none; } .nav-pills { width: 150px; } .nav-pills.affix { top ...
- Support Vector Machine(1):线性可分集的决策边界
与Logistuc Regression相比,SVM是一种优化的分类算法,其动机是寻找一个最佳的决策边界,使得从决策边界与各组数据之间存在margin,并且需要使各侧的margin最大化.比较容易理解 ...
- mooc-IDEA alter enter--008
十四.IntelliJ IDEA -alter enter 1.提示一:自动创建函数 2.提示二.list replace 等于 3.提示三.字符串formate或build 等于 等于 等于 4.实 ...
- docker实现分布式项目部署
docker的安装及基本命令这里就略过了,可以看我的这篇笔记https://www.cnblogs.com/pyweb/p/11351878.html. 这次需要在docker上部署两个项目,整体的流 ...
- Self-Attention 和 Transformer
1.Self-Attention 之前的RNN输入是难以并行化的,我们下一个输入可能依赖前一个输出,只有知道了前面的输出才能计算后面的输出. 于是提出了 self-attention ,但是这时候 $ ...
- 《JAVA设计模式》之组合模式(Composite)
在阎宏博士的<JAVA与模式>一书中开头是这样描述合成(Composite)模式的: 合成模式属于对象的结构模式,有时又叫做“部分——整体”模式.合成模式将对象组织到树结构中,可以用来描述 ...
- Linux固定ip配置
第一步:查看网络信息 [root@localhost ~]# ifconfig ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu ...
- python eval( ) 使用详解
1.解析表达式 (表达式是str类型)----最常用 a = 12 b = "联播" result1 = eval(a+3) # resu ...
- vue iview分页
距离上次博客更新已经快一个月了,期间也有想法在空闲的时候更新几篇博文. 燃鹅,最近懒癌作祟,丢掉的东西越来越多,再不遏止的话就真成癌了. 趁着刚看完一篇心灵鸡汤,让打满鸡血的我总结下前段时间用到的iv ...
- vue 实现模糊检索,并根据其他字符的首字母顺序排列
昨天让我做一个功能,实现一个模糊检索,我就想,那做呗,然后开始正常的开发 代码如下: HTML VUE 因为是实时的,所以写了将逻辑写到了watch中 五分钟搞定. 我以为这就完了,然而产品的需求 ...