Go匿名结构体使用场景
1. 定义
在 Go 语言中,匿名结构体(Anonymous Struct)是一种没有显式命名的结构体类型。你可以直接在代码中定义并使用匿名结构体,而不需要为其定义一个单独的类型名称。匿名结构体通常用于临时数据结构或一次性使用的场景。
匿名行为的设计带来了一些理解上的困难,但是熟悉了匿名设计的使用后,你会发现匿名设计在某些特定场景可以帮助大家写出更简洁、更优雅、更高效和更安全的代码。
2. 代码使用示例
2.1 简单示例
package mainimport ("fmt"
)func main() {// 定义并初始化一个匿名结构体person := struct {Name stringAge int}{Name: "Alice",Age: 30,}// 打印匿名结构体的字段fmt.Println("Name:", person.Name)fmt.Println("Age:", person.Age)
}
结果:
Name: Alice
Age: 30
在这个示例中,struct { Name string; Age int } 定义了一个匿名结构体类型,并直接初始化了一个 person 变量。你可以像访问普通结构体一样访问匿名结构体的字段。
2.2 匿名结构体的嵌套
你也可以在匿名结构体中嵌套其他匿名结构体:
package mainimport ("fmt"
)func main() {// 定义并初始化一个嵌套的匿名结构体employee := struct {Name stringAge intAddress struct {City stringState string}}{Name: "Bob",Age: 25,Address: struct {City stringState string}{City: "New York",State: "NY",},}// 打印嵌套的匿名结构体的字段fmt.Println("Name:", employee.Name)fmt.Println("Age:", employee.Age)fmt.Println("City:", employee.Address.City)fmt.Println("State:", employee.Address.State)
}
结果:
Name: Bob
Age: 25
City: New York
State: NY
在这个示例中,employee 是一个包含嵌套匿名结构体的匿名结构体。你可以通过 employee.Address.City 和 employee.Address.State 访问嵌套结构体的字段。
2.3 总结
- struct { ... }:定义一个匿名结构体类型。
- 匿名结构体通常用于临时数据结构或一次性使用的场景。
- 你可以在匿名结构体中嵌套其他匿名结构体。
- 通过使用匿名结构体,你可以在 Go 程序中方便地定义和使用临时数据结构,而无需为其定义单独的类型名称。
3. 使用场景
3.1 造测试数据
匿名结构体可以和切片结合起来使用,通常用于创建一组测试数据。
package mainimport "fmt"func main() {// 测试数据var people = []struct {Name stringAge int}{{"Li", 31},{"Yang", 28},{"Liu", 27},{"Tong", 30},}fmt.Println(people)
}
结果:
[{Li 31} {Yang 28} {Liu 27} {Tong 30}]
3.2 处理Json
将一个json串转化为map[string]interface{})结构
package mainimport ("encoding/json""fmt""reflect"
)const jsonStr = `{
"name":"Liuhui",
"id":712364567213544422
}`func main() {obj := make(map[string]interface{})_ = json.Unmarshal([]byte(jsonStr), &obj)fmt.Printf("%+v\n", obj)fmt.Println("-------------------")objBytes, _ := json.Marshal(obj)fmt.Println(string(objBytes))fmt.Printf("%+v\n", reflect.TypeOf(obj["id"]).Name())
}
结果(可以看到精度丢失):
map[id:7.123645672135444e+17 name:Liuhui]
-------------------
{"id":712364567213544400,"name":"Liuhui"}
float64
在当前代码中,json.Unmarshal 将 JSON 数据解析到一个 map[string]interface{} 中。由于 interface{} 类型可以表示任何 Go 类型,因此在解析 JSON 时,Go 会根据 JSON 值的类型自动选择合适的 Go 类型。对于大整数(如 712364567213544422),Go 默认会将其解析为 float64 类型。
为什么会丢失精度?
float64 的精度限制:float64 类型在表示大整数时可能会丢失精度。float64 使用 64 位来表示数值,其中一部分用于表示指数,因此对于非常大的整数,float64 无法精确表示。
interface{} 的类型推断:当 JSON 中的整数非常大时,json.Unmarshal 会将其解析为 float64,因为 float64 可以表示比 int64 更大的数值范围。然而,float64 的精度不足以精确表示所有大整数,从而导致精度丢失。
如何避免精度丢失?
为了避免精度丢失,可以使用匿名结构体来解析 JSON 数据,并明确指定整数类型的字段。例如:
package mainimport ("encoding/json""fmt"
)const jsonStr = `{
"name":"Liuhui",
"id":712364567213544422
}`func main() {obj := struct {Name string `json:"name"`Id int64 `json:"id"`}{}_ = json.Unmarshal([]byte(jsonStr), &obj)fmt.Printf("%+v\n", obj)fmt.Println("-------------------")objBytes, _ := json.Marshal(obj)fmt.Println(string(objBytes))
}
结果:
{Name:Liuhui Id:712364567213544422}
-------------------
{"name":"Liuhui","id":712364567213544422}
嵌套的 JSON
对于嵌套的 JSON,也可以使用内嵌的匿名结构体来解析:
package mainimport ("encoding/json""fmt"
)const jsonStr = `{
"name":"Liuhui",
"id":712364567213544422,
"job":{
"Company":"DouYin"}
}`func main() {obj := struct {Name string `json:"name"`Id int64 `json:"id"`Job struct {Company string `json:"company"`} `json:"job"`}{}_ = json.Unmarshal([]byte(jsonStr), &obj)fmt.Printf("%+v\n", obj)fmt.Println("-------------------")objBytes, _ := json.Marshal(obj)fmt.Println(string(objBytes))
}
结果:
{Name:Liuhui Id:712364567213544422 Job:{Company:DouYin}}
-------------------
{"name":"Liuhui","id":712364567213544422,"jobc":{"company":"DouYin"}}
3.3 嵌套锁
我们经常遇到多个goroutine要操作共享变量,为了并发安全,需要对共享变量的读写加锁。
这个时候通常需要定义一个和共享变量配套的锁来保护共享变量。
匿名结构体和匿名字段相结合,可以写出更优雅的代码来保护匿名结构体里的共享变量,实现并发安全。
package mainimport ("fmt""sync"
)func main() {// hits 匿名结构体变量// 这里同时用到了匿名结构体和匿名字段, sync.Mutex是匿名字段// 因为匿名结构体嵌套了sync.Mutex,所以就有了sync.Mutex的Lock和Unlock方法var hits struct {sync.Mutexn int}var wg sync.WaitGroupN := 1000// 启动100个goroutine对匿名结构体的成员n同时做读写操作wg.Add(N)for i := 0; i < 1000; i++ {go func() {defer wg.Done()hits.Lock()defer hits.Unlock()hits.n++}()}wg.Wait()fmt.Println(hits.n) // 1000
}
4. 总结
匿名结构体可以让我们不用先定义结构体类型,再定义结构体变量。让结构体的定义和变量的定义可以结合在一起,一次性完成。
匿名结构体有以下应用场景:
- 构造测试数据
- 处理Json
- 嵌套锁
相关文章:
Go匿名结构体使用场景
1. 定义 在 Go 语言中,匿名结构体(Anonymous Struct)是一种没有显式命名的结构体类型。你可以直接在代码中定义并使用匿名结构体,而不需要为其定义一个单独的类型名称。匿名结构体通常用于临时数据结构或一次性使用的场景。 匿名…...
Vue 发布十年了!你知道我这十年是怎么过的吗?
2014 年 2 月 3 日,Vue 在 Hacker News 上首次亮相。十年后的今天,Vue 已经成为使用最广泛的前端框架之一,拥有了一个非常丰富的生态系统。本文来梳理一下 Vue.js 十年以来的重要里程碑! 尤雨溪,无疑是 Vue.js 背后的灵…...
Unity 6 来袭
这里写自定义目录标题 1.提升渲染性能1.1 降低CPU开销 Lower CPU overhead1.2.减少内存带宽1.3.高档低分辨率帧2.多人游戏创作3.扩大多平台覆盖范围3.1.增进Android平台开发4.使用Runtime AI解锁各种可能性4.1.Unity Muse4.2.Unity Sentis5.实现更具吸引力的视觉效果5.1.自适应…...
SpringMVC课时1
一:SpringMVC Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet,负责表述层(控制层)实现简化。 由于 Spring MVC 本身就是 Spring 框架的一部分,和 Spring 框架是无缝集成。 二:SSM的主要作用 三:SpringMVC的原理架构图 …...
【小白学机器学习30】样本统计的核心参数:均值/期望,方差,标准差,标准值。
目录 1 为什么我们要搞出来这么多指标/参数? 1.1 描述统计学为啥要搞出来这么多复杂的参数?什么平均值等 1.2 所以,需要用少数几个关键数据代表1群数据 1.2.1 平均值 1.2.2 平均值的问题:方差 2 代表性的数据1:…...
flink1.17.2安装和使用
版本:flink1.17.2 单机模式 配置 # 为了在别处连接flink-web rest.bind-address: 0.0.0.0命令 # 启动集群 bin/start-cluster.sh # 关闭集群 bin/stop-cluster.sh使用 使用浏览器连接 ip:8081 使用flink-web...
C向C++入门-- C语言填坑
1.c参考文档 我们在学习c中需要查找参照信息到是从这些文档中得到。 https://legacy.cplusplus.com/reference/ 标准只更新到C11,但是以头⽂件形式呈现,内容⽐较易看好懂。 https://zh.cppreference.com/w/cpp https://en.cppreference.com/w/ 后两…...
扫雷游戏(C语言详解)
扫雷游戏(C语言详解) 放在最前面的1、前言(扫雷游戏的简介)2、扫雷游戏的规则(简易版)3、代码实现(3.1)提醒一下:( i ) 提醒1:( ii ) 提醒2: &…...
信刻全自动光盘摆渡系统
随着各种数据传输、储存技术、信息技术的快速发展,保护信息安全是重中之重。各安全领域行业对跨网数据交互需求日益迫切。针对于业务需要与保密规范相关要求,涉及重要秘密信息,需做到安全的物理隔离,并且保证跨网数据高效安全传输…...
计算机网络的数据链路层
计算机网络的数据链路层 数据链路层是OSI参考模型中的第二层,它位于物理层之上,网络层之下。数据链路层的主要功能是在物理层提供的服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节点的目标机网络层。…...
从0开始搭建一个生产级SpringBoot2.0.X项目(三)SpringBoot接口统一返回和全局异常处理
前言 最近有个想法想整理一个内容比较完整springboot项目初始化Demo。 SpringBoot接口统一返回和全局异常处理,使用ControllerAdvice ExceptionHandler 的组合来实现。 一、pom文件新增依赖 <dependency><groupId>com.alibaba</groupId><ar…...
Mybatis-plus-扩展功能
Mybatis-plus-扩展功能 一:代码生成器 AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。 功能的演示:…...
【AI辅助】AWS Toolkit+AmazonQ
#偶然看到网上某up主用的这个AI工具,感觉还挺实用的,推荐大家~我们不可阻挡AI的攻势,但是成为利用它的人,也是反侵占的方式呢# AWS toolkit Amazon Q 安装 VScode--Extensions--搜索工具--安装 安装后,工具栏会多出对…...
云手机简述(概况,使用场景,自己部署云手机)
背景 最近经常会看到云手机的相关广告,手痒难耐,了解一下。 我的主要需求: Android 已 root,能够做一些自动化等高级功能。能够通过 远程adb 控制手机。能够尽量的少花钱,最好是能够提供动态创建删除手机的方式&…...
Java已死,大模型才是未来?
作者:不惑_ 引言 在数字技术的浪潮中,编程语言始终扮演着至关重要的角色。Java,自1995年诞生以来,便以其跨平台的特性和丰富的生态系统,成为了全球范围内开发者们最为青睐的编程语言之一 然而,随着技术的…...
NCCL安装(Ubuntu等)
目录 一、NCCL的定义二、安装NCCL的原因1、加速多GPU通信2、支持流行的深度学习框架3、提高计算效率4、易于使用和集成5、可扩展性 三、NCCL安装方法1、下载安装包2、更新APT数据库3、使用APT安装libnccl2包,另外,如果需要使用NCCL编译应用程序ÿ…...
加载视频显示 - python 实现
#-*-coding:utf-8-*- # date:2021-03-21 # Author: DataBall - Xian # Function: 加载视频并显示import cv2 if __name__ "__main__":#加载视频cap cv2.VideoCapture(./video/1.mp4)while True:ret, img cap.read()# 获取相机图像if ret True:# 如果 ret 返回值为…...
数据结构模拟题[五]
数据结构试卷(五) 一、选择题 (20 分) 1.数据的最小单位是( )。 (A) 数据项 (B) 数据类型 (C) 数据元素 (D) 数据变量 2.设一组初始记录关键字序列为 (50 ,40, 95,20…...
IDEA切换窗口快捷键失效
问题描述: 在idea中,如果切换窗口的快捷键(Alt Tab)失效了,可以通过清除缓存的方式修复...
QT中使用图表之QChart绘制X轴为日期时间轴的折线图
显然X轴是日期时间轴的话,那么我们使用的轴类就得是QDateTimeAxis QChart中日期时间轴的精度是毫秒 因此图表里面的数据的x值需要是一个毫秒数,才能显示出来 --------------------------------------------------------------------------------------…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...
Redis上篇--知识点总结
Redis上篇–解析 本文大部分知识整理自网上,在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库,Redis 的键值对中的 key 就是字符串对象,而 val…...
篇章一 论坛系统——前置知识
目录 1.软件开发 1.1 软件的生命周期 1.2 面向对象 1.3 CS、BS架构 1.CS架构编辑 2.BS架构 1.4 软件需求 1.需求分类 2.需求获取 1.5 需求分析 1. 工作内容 1.6 面向对象分析 1.OOA的任务 2.统一建模语言UML 3. 用例模型 3.1 用例图的元素 3.2 建立用例模型 …...
