首页 > 其他分享 >深入浅出Go语言:反射应用解密!

深入浅出Go语言:反射应用解密!

时间:2024-04-11 09:00:51浏览次数:40  
标签:反射 fmt 深入浅出 解密 reflect Go query

深入浅出Go语言:反射应用解密!

原创 麻凡 麻凡 2024-03-06 09:02 湖南 1人听过

在Go语言编程中,反射是一项高级技术,能够在程序运行时检查变量和值的类型。你可能会问,为什么我们需要反射呢?让我们一起揭开这个神秘的面纱。

为什么需要反射

大多数情况下,我们在编写代码时都可以在编译时确定变量的类型。但是,有时候我们需要处理那些类型不确定的情况。比如,我们想要编写一个通用的函数,能够根据不同的结构体类型生成 SQL 插入查询语句。

package main

import (
    "fmt"
)

type order struct {
    ordId      int
    customerId int
}

func main() {
    o := order{
        ordId:      1234,
        customerId: 567,
    }
    fmt.Println(o)
}

上面的代码很简单,但如果我们想要让它更加通用,能够适用于不同的结构体类型,该怎么办呢?这就是反射发挥作用的时候了。

reflect 包:揭开反射的面纱

在 Go 中,反射是由 reflect 包来实现的。它提供了一种方法来识别变量的类型和值,正是我们所需要的。

让我们来了解一下反射包中的一些重要概念:

  • reflect.Type 和 reflect.Valuereflect.Type 表示接口的具体类型,而 reflect.Value 则表示接口的具体值。这两者是我们进行反射操作的基础。

  • reflect.Kind:Kind 类型表示 reflect.Type 的具体种类。通过 Kind,我们可以了解变量的底层类型是什么。

  • NumField() 和 Field() 方法:NumField() 方法返回结构体中的字段数,而 Field(i int) 方法返回指定索引的字段的 reflect.Value

  • Int() 和 String() 方法:Int() 方法可以将 reflect.Value 转换为 int64 类型的值,而 String() 方法则可以将其转换为 string 类型的值。

让我们将这些概念应用到实际代码中。

package main

import (
    "fmt"
    "reflect"
)

type order struct {
    ordId      int
    customerId int
}

func createQuery(q interface{}) {
    if reflect.ValueOf(q).Kind() == reflect.Struct {
        t := reflect.TypeOf(q).Name()
        query := fmt.Sprintf("insert into %s values(", t)
        v := reflect.ValueOf(q)
        for i := 0; i < v.NumField(); i++ {
            switch v.Field(i).Kind() {
            case reflect.Int:
                if i == 0 {
                    query = fmt.Sprintf("%s%d", query, v.Field(i).Int())
                } else {
                    query = fmt.Sprintf("%s, %d", query, v.Field(i).Int())
                }
            case reflect.String:
                if i == 0 {
                    query = fmt.Sprintf("%s\"%s\"", query, v.Field(i).String())
                } else {
                    query = fmt.Sprintf("%s, \"%s\"", query, v.Field(i).String())
                }
            default:
                fmt.Println("Unsupported type")
                return
            }
        }
        query = fmt.Sprintf("%s)", query)
        fmt.Println(query)
        return
    }
    fmt.Println("Unsupported type")
}

func main() {
    o := order{
        ordId:      456,
        customerId: 56,
    }
    createQuery(o)

    e := employee{
        name:    "Naveen",
        id:      565,
        address: "Coimbatore",
        salary:  90000,
        country: "India",
    }
    createQuery(e)

    i := 90
    createQuery(i)
}

在上面的代码中,我们使用反射实现了一个通用的 SQL 查询生成器。通过反射,我们可以根据不同的结构体类型动态生成 SQL 插入语句,使我们的代码更加灵活和通用。

结论

反射是 Go 语言中一项强大而高级的技术。虽然它能够带来很大的灵活性,但也应该谨慎使用。反射代码往往更加难以理解和维护,因此应该尽可能地避免使用,只在必要时使用。

麻凡 码农一枚,爱折腾,分享技术、副业与生活思考。在未知路上,一起挖坑填坑,探索无限可能。 31篇原创内容 公众号

推荐阅读

 

麻凡

 一份鼓励,一份认可! 

赞赏二维码喜欢作者

深入浅出Go语言26 编程语言25 深入浅出Go语言 · 目录 上一篇深入浅出Go语言:Go语言文件操作全解析下一篇深入浅出Go语言:结构 vs 类,Go 中的 OOP 阅读 248 ​ 喜欢此内容的人还喜欢   解决Linux服务器下SSH连接慢的问题     我看过的号 写代码的SharkChili 不看的原因   Go实现DNF游戏玩家地图场景控制实战     Golang技术客栈 不看的原因   Docker多阶段构建:如何构建更小的镜像     程序小媛 不看的原因   作者已设置关注后才可以留言       麻凡            

人划线

标签:反射,fmt,深入浅出,解密,reflect,Go,query
From: https://www.cnblogs.com/cheyunhua/p/18127968

相关文章

  • #莫队二次离线,根号分治#洛谷 5398 [Ynoi2018] GOSICK
    题目\(m\)组询问求\(\sum_{l\leqi,j\leqr}[a_i\bmoda_j==0],n,m,a_i\leq5\times10^5\)分析设\(f(l,r,x)\)表示\(i或j\in[1,x],i或j\in[l,r]\)时的答案,\(g_x\)表示\([1,x]\)的答案,根号的做法可以通过三秒由于涉及区间内的求值,需要在莫队的基础上二次离线,那......
  • go写入配置文件
    packageinstallimport("fmt""io/ioutil""os"v2"gopkg.in/yaml.v2""github.com/fanux/sealos/net""github.com/fanux/sealos/pkg/logger")const(defaultConfigPath="......
  • goto语句
    今天给大家分享一个小知识----goto语句。goto语句就是可以随意无条件的转移语句,运用形式是:标记名:...        goto标记名;这两个中间可以写任意内容,标记名也可以在goto语句后面,位置随意。给大家分享一个好玩的例子:一个定时关机程序,输入我是小狗,取消关机,输......
  • django simpleui 的list_display添加自定义列、显示图片 及alert弹窗的设置方法
    参考djangosimpleui的list_display添加自定义列、显示图片及alert弹窗的设置方法-CSDN博客环境:python:3.8.xDjango:3.2.xDjango-simpleui:2021.x先定义下模型#models.pyclassDog(models.Model):name=models.CharField(max_length=15,verbose_name='小狗名字')......
  • Go 源码之旅-开篇
    欢迎来到《Go源码之旅》专栏!在这个专栏中,我们将深入探索Go编程语言的内部数据结构的工作原理,一起踏上一段令人兴奋的源码之旅。我们将一步步解析关键的数据结构底层工作原理以及一些常用框架的设计原理及其源码。无论你是初学者还是有经验的开发人员,这个专栏都将为你提......
  • 牛蛙!GoFrame2.7正式版的监控组件真是及时雨
    声明:本文首发在同名公众号:王中阳Go,未经授权禁止转载。......
  • 基于Golang的Nano游戏服务器框架
    在游戏开发过程中,一个高效的服务器框架是至关重要的。Nano正是这样一个框架,它以Golang为基础,提供了轻量级、高性能的服务器解决方案。下面,我们将深入探讨Nano的设计理念、核心特性以及如何在实战中使用它。Nano框架概述Nano是一个针对游戏服务器的框架,能够帮助开发者快速......
  • 2024-04-10:用go语言,考虑一个非负整数数组 A, 如果数组中相邻元素之和为完全平方数,我们
    2024-04-10:用go语言,考虑一个非负整数数组A,如果数组中相邻元素之和为完全平方数,我们称这个数组是正方形数组。现在要计算A的正方形排列的数量。两个排列A1和A2被认为是不同的,如果存在至少一个索引i,满足A1[i]!=A2[i]。输入:[1,17,8]。输出:2。答案2024-04-10:来自左......
  • GPT-4 Turbo 融合视觉能力;Google 新添 AI 视频应用 Vids丨 RTE 开发者日报 Vol.181
      开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑的个人观点......
  • Python 一骑绝尘,Go 进入 TOP 10 | TIOBE 3 月榜单发布
    近日,3月TIOBE编程语言榜单已最新出炉,一起来看看本月有什么值得关注的新变化吧!1、Python可谓“一骑绝尘”与前几个月相比,本月的Python可谓“一骑绝尘”——哪怕与第二名的C语言(11.17%)比较,其市场份额(15.63%)都领先了近4.5%。得益于过去一年AI热潮席卷全球,被许多人......