go底层系列-struct底层实现

struct

前言

  • Go的struct声明允许字段附带 Tag 来对字段做一些标记
  • 该 Tag 不仅仅是一个字符串那么简单,因为其主要用于反射场景
  • reflect 包中提供了操作 Tag 的方法,所以 Tag 写法也要遵循一定的规则。

Tag的本质

Tag规则
  • Tag 本身是一个字符串,但字符串中却是: 以空格分隔的 key:value 对 。
    • key : 必须是非空字符串,字符串不能包含控制字符、空格、引号、冒号。
    • value : 以双引号标记的字符串 注意:冒号前后不能有空格
// 如下
type Server struct {
	ServerName string `key1: "value1" key11:"value11"`
	ServerIP string `key2: "value2"`
}
Tag是Struct的一部分
  • Tag 只有在反射场景中才有用
  • 而反射包中提供了操作 Tag 的方法

在说方法前,先了解一下 Go是如何管理struct字段的

在这里插入图片描述

可见

  • 描述一个结构体成员的结构中包含了 StructTag
  • 而其本身是一个 string 。也就是说 Tag 其实是结构体字段的一个组成部分
获取Tag
  • StructTag 提供了 Get(key string) string 方法来获取 Tag
package main

import (
	"fmt"
	"reflect"
)

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"))
}

Tag存在的意义

  • 本文示例中tag没有任何实际意义
    • 这是为了阐述tag的定义与操作方法
    • 也为了避免与你之前见过的诸 如 json:xxx 混淆。
  • 使用反射可以动态的给结构体成员赋值
  • 正是因为有tag,在赋值前可以使用tag来决定赋值的动作
  • 官方 的 encoding/json 包,可以将一个JSON数据 Unmarshal 进一个结构体
    • 此过程中就使用了Tag.
  • 该包定义一些规则,只要参考该规则设置tag就可以将不同的JSON数据转换成结构体
  • 总之
    • 正是基于struct的tag特性,才有了诸如json、orm等等的应用
    • 或许,你可以定义另一种tag规则,来处理你特有的数据。

Tag常见用法

  • JSON数据解析
  • ORM映射
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值