golang面试题:reflect(反射包)如何获取字段tag​?为什么json包不能导出私有变量的tag?

news2024/11/20 20:19:22

在这里插入图片描述

问题

json包里使用的时候,会结构体里的字段边上加tag,有没有什么办法可以获取到这个tag的内容呢?

举例

tag信息可以通过反射(reflect包)内的方法获取,通过一个例子加深理解。

package main

import (
    "fmt"
    "reflect"
)

type J struct {
    a string //小写无tag
    b string `json:"B"` //小写+tag
    C string //大写无tag
    D string `json:"DD" otherTag:"good"` //大写+tag
}

func printTag(stru interface{}) {
    t := reflect.TypeOf(stru).Elem()
    for i := 0; i < t.NumField(); i++ {
        fmt.Printf("结构体内第%v个字段 %v 对应的json tag是 %v , 还有otherTag? = %v \n", i+1, t.Field(i).Name, t.Field(i).Tag.Get("json"), t.Field(i).Tag.Get("otherTag"))
 }
}

func main() {
    j := J{
      a: "1",
      b: "2",
      C: "3",
      D: "4",
    }
    printTag(&j)
}

输出

结构体内第1个字段 a 对应的json tag是 , 还有otherTag? =
结构体内第2个字段 b 对应的json tag是 B , 还有otherTag? =
结构体内第3个字段 C 对应的json tag是 , 还有otherTag? =
结构体内第4个字段 D 对应的json tag是 DD , 还有otherTag? = good

解释

  • printTag方法传入的是j的指针。
  • reflect.TypeOf(stru).Elem()获取指针指向的值对应的结构体内容。NumField()可以获得该结构体含有几个字段。
  • 遍历结构体内的字段,通过t.Field(i).Tag.Get(“json”)可以获取到tag为json的字段。
  • 如果结构体的字段有多个tag,比如叫otherTag,同样可以通过t.Field(i).Tag.Get(“otherTag”)获得。

再补一句

上篇文章 提到json包不能导出私有变量的tag是因为取不到反射信息的说法,但是直接取t.Field(i).Tag.Get(“json”)却可以获取到私有变量的json字段,是为什么呢?

其实准确的说法是,json包里不能导出私有变量的tag是因为json包里认为私有变量为不可导出的Unexported,所以跳过获取名为json的tag的内容。

具体可以看/src/encoding/json/encode.go:1070的代码。

func typeFields(t reflect.Type) []field {
    // 注释掉其他逻辑...
    // 遍历结构体内的每个字段
    for i := 0; i < f.typ.NumField(); i++ {
        sf := f.typ.Field(i)
        isUnexported := sf.PkgPath != ""
        // 注释掉其他逻辑...
        if isUnexported {
            // 如果是不可导出的变量则跳过
            continue
        }
        // 如果是可导出的变量(public),则获取其json字段
        tag := sf.Tag.Get("json")
        // 注释掉其他逻辑...
    } 
    // 注释掉其他逻辑... 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DevSecOps 中的漏洞管理(下)

建立漏洞管理程序以支持DevSecOps 在讨论DevSecOps及DevOps模型中包含安全性的重要性时&#xff0c;建立有效的漏洞管理实践是非常重要的。这可以通过将漏洞管理设置为程序来实现。 我们可以开始对IT组织进行漏洞管理评估。人们经常问的问题可能是&#xff0c;既然已经建立了…

第一章 计算机系统概述 四、操作系统的运行机制

注:很多人习惯把Linux、Windows、MacOS的“小黑框”中使用的命令也称为“指令”&#xff0c;其实这是“交互式命令接口”&#xff0c;注意与本节的“指令”区别开。本节中的“指令”指二进制机器指令。 一、CPU的两种状态 状态的切换&#xff1a; 内核态转用户态&#xff0c;是…

【个人博客系统 × Redis】“最后的升级“ · 连接Redis · Redis的基本使用

【JavaEE】进阶 个人博客系统&#xff08;7&#xff09; 文章目录 【JavaEE】进阶 个人博客系统&#xff08;7&#xff09;1. linux安装Redis1.1 通过yum商店下载Redis1.2 启动Redis1.3 操作Redis 2. Redis的基本使用&#xff08;关键字大小写不区分&#xff09;2.1 set2.2 g…

SUMPRODUCT函数

SUMPRODUCT函数返回相应范围或数组的个数之和。 默认操作是乘法&#xff0c;但也可以执行加减除运算。 本示例使用 SUMPRODUCT 返回给定项和大小的总销售额&#xff1a; SUMPRODUCT 匹配项 Y/大小 M 的所有实例并求和&#xff0c;因此对于此示例&#xff0c;21 加 41 等于 62。…

UML-用例图

目录 一、UML 什么是UML&#xff1f; 为什么要用UML&#xff1f; UML图有哪些&#xff1f; 二、用例图 用例图摘要 用例图主要元素 1. 参与者&#xff08;Actor&#xff09; 2. 用例(Use Case) 3. 关系 4. 边界 用例图之间的关系 &#xff08;1&#xff09;参与者…

Figma实用插件速收藏!精选19个干货插件大公开!

Figma 如今有着大量的插件&#xff0c;在 UI/UX 设计领域&#xff0c;很多工作已经不用真的从零开始做了。用好 Figma 插件&#xff0c;往往能让设计工作事半功倍。不过其中的插件素质差别很大&#xff0c;需要仔细筛选。不过如果你选择了对的插件&#xff0c;合理的设置&#…

SpringCloud(17~21章):Alibaba入门简介、Nacos服务注册和配置中心、Sentinel实现熔断与限流、Seata处理分布式事务

17 SpringCloud Alibaba入门简介 17.1 why会出现SpringCloud alibaba Spring Cloud Netflix项目进入维护模式 https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now 说明 Spring Cloud Netflix Projects Entering Maintenance Mode 什么是维护模…

c高级day4(shell)

实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数写一个函数&#xff0c;输出当前用户的uid和gid&#xff0c;并使用变量接收结果

20230911 Shell指令数组以及函数值传递,值返回

实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 #!/bin/bashfunction fun() {sum0for ((i0;i<$var;i))do(( sumarr[i] ))doneecho $sum } read -p "输入该数组个数: " var for((j0;j<$var;j)) doread -p "输入数组第$j个值: " arr[j] …

Jmeter引入外部jar包以满足加密数据的Post请求

目录 一、把项目打成jar包 1、创建一个Maven项目&#xff0c;并保证可以正常运行。 2、把工具类放置项目中&#xff0c;确保无报错且能够正常使用。 3、打包 4、验证 jar包是否有效 5、你想打多个工具类的包 二、在jmeter中使用 1、把jar包放到jmeter仓库下&#xff0c;…

Mixin从理论到实践

mixin从理论到实践 mixin从理论到实践一、什么是mixin二、使用mixin三、mixin的合并策略四、mixin辨析五、个人实践 mixin从理论到实践 一、什么是mixin mixin混入 — Vue.js (vuejs.org) 官方解释&#xff1a; 混入 (mixin) 提供了一种非常灵活的方式&#xff0c;来分发 Vue …

uni-app:自带的消息提示被遮挡的解决办法(自定义消息提示框)

效果&#xff1a; 代码&#xff1a; 1、在最外层或者根组件的模板中添加一个容器元素&#xff0c;用于显示提示消息。例如&#xff1a; <div class"toast-container" v-if"toastMessage"><div class"toast-content">{{ toastMessa…

shell脚本中分支结构、循环、以及函数的介绍和使用

练习 实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 #!/bin/bash function sum() {sum0for i in ${arr[*]}do((sumi))doneecho "数组和为&#xff1a;"$sum } read -p "请输入一个数组&#xff1a;" -a arr sum arr写一个函数&#xff0c…

华为云云服务器云耀L实例评测 | 从零开始:华为云云服务器L实例使用教程

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Mediasoup源码介绍

一、Mediasoup 整体结构 整个Mediasoup库通过Nodejs管理&#xff0c;比如整体逻辑、worker、router、producer、consumer...都是通过JS进行管理的。 其底层的数据传输是通过C部分进行控制的&#xff0c;通过NodeJs来控制C部分&#xff0c;以实现整体的数据传输效 二、Mediasou…

Python最好用的可视化库(从低级到高级)

今天&#xff0c;我将深入探讨Python中的数据可视化世界&#xff0c;更具体地说&#xff0c;我们如何利用一些官方库来可视化SQL查询的结果&#xff0c;已有的“轮子”可以让这个过程变得轻松愉快。我们接下来将分别给出几个库的简介及运行结果。 Matplotlib&#xff1a;你可靠…

想要精通算法和SQL的成长之路 - 课程表IV

想要精通算法和SQL的成长之路 - 课程表IV 前言一. 课程表IV &#xff08;拓扑排序&#xff09; 前言 想要精通算法和SQL的成长之路 - 系列导航 做这个题目之前可以回顾一下&#xff1a;课程表II 一. 课程表IV &#xff08;拓扑排序&#xff09; 原题链接 这道题目在课程表I…

通过Git Bash将本地文件上传到本地github

1. 新建一个仓库&#xff08; Repository&#xff09; 1.1登录Github&#xff0c;点击个人头像&#xff0c;点击Your repositories&#xff0c;点击New。 1.2 填写信息 Repository name: 仓库名称 Description(可选): 仓库描述介绍,不是必填项目。~~建议填写上哦&#xff01;…

排序算法:快速排序(三种排序方式、递归和非递归)

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下有关排序算法的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通…

PMP中十大知识领域及敏捷部分

今天给大家分享一篇PMP考试中十大知识领域及敏捷部分。希望正在备考11月PMP的宝子们能够清楚地拿捏重难点&#xff0c;稳稳上岸&#xff01; 我是胖圆~欢迎大家关注留言&#xff01; 或者移步公众号【胖圆说PM】找我