Golang 利用反射对结构体优雅排序的操作方法

最近开始实习,工作技术栈主要Python和Golang,目前的任务把Python模块重构为GO模块,然后出现了一个问题,就是要将一个结构体按结构体中各个字段进行排序,然后写入Redis,对于Pyhon来说for循环就能解决,但是对于Go语言来说,每一次排序都要写一个比较函数,写出来的代码太丑,非常长,代码结构是一致,只是比较字段不一样而已,个人无法接受啊,网上搜索也没搜索到合适解决方法,所以自己想了一个解决方法来优雅排序。

比较函数:

func reflectCmp(i, j interface{}, fieldName string) bool {  //按传入fieldName 排序
	valI := reflect.ValueOf(i).FieldByName(fieldName).Interface()
	valJ := reflect.ValueOf(j).FieldByName(fieldName).Interface()
	switch s := valI.(type) {
	case string:
		return s < valJ.(string)
	case float64:
		return s < valJ.(float64)
	case int:
		return s < valJ.(int)
	default:
		fmt.Println("The type is unknown")
	}
	return true
}

将自己要比较的类型加入switch中即可。

假设我们有一个结构体为

type person struct {
	Age int
	Name string
}

那么如何来排序呢?

func main() {
	pSlice := []person{{20,"a"},{15,"be"},{32,"cc"},{2,"aa"}}
	var p person
	typeOfA := reflect.TypeOf(p)

	// 遍历结构体所有成员
	for i := 0; i < typeOfA.NumField(); i++ {
		// 获取每个成员的结构体字段类型
		fieldType := typeOfA.Field(i)
		sort.Slice(pSlice,func(i, j int) bool {
			return reflectCmp(pSlice[i],pSlice[j],fieldType.Name)
		})
		fmt.Println(pSlice)
	}
}

运行结果

利用反射,不管结构体有多少个字段,我们都能用一个for 排序即可优雅完成排序。

到此这篇关于Golang 利用反射对结构体优雅排序的文章就介绍到这了,更多相关Golang反射结构体排序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang结构体与json格式串实例代码

    具体代码如下所示: package main import ( "encoding/json" "fmt" ) type IT struct { //一定要注意这里的成员变量的名字首字母必须是大写 Company string Subjects []string Isok bool Price float64 } func main() { s := IT{"zyg", []string{"go", "python&

  • golang 结构体初始化时赋值格式介绍

    golang在给结构体赋值初始值时,用:分割k,v值 x := ItemLog{ Id: GetUuid(), ItemId: u.Id, UsrId: "123", Name: u.Name, Price: u.Price, Desc: u.Desc, Status: u.Status, DevArea: u.DevArea, } 补充:golang 结构体作为map的元素时,不能够直接赋值给结构体的某个字段 引入: 错误 Reports assignments directly t

  • golang 实现两个结构体复制字段

    实际工作中可能会有这样的场景: 两个结构体(可能类型一样), 字段名和类型都一样, 想复制一个结构体的全部或者其中某几个字段的值到另一个(即merge操作), 自然想到可以用反射实现 package main import "fmt" import "reflect" // 用b的所有字段覆盖a的 // 如果fields不为空, 表示用b的特定字段覆盖a的 // a应该为结构体指针 func CopyFields(a interface{}, b interface

  • golang修改结构体中的切片值方法

    golang修改结构体中的切片值,直接传结构体地址就可以 package main import "fmt" type rspInfo struct { KeyWords string `json:"key_words"` Value []string `json:"value"` } func setSlice(te *[]string){ str := "12" *te = append(*te,str) } //结构提传

  • Golang 利用反射对结构体优雅排序的操作方法

    最近开始实习,工作技术栈主要Python和Golang,目前的任务把Python模块重构为GO模块,然后出现了一个问题,就是要将一个结构体按结构体中各个字段进行排序,然后写入Redis,对于Pyhon来说for循环就能解决,但是对于Go语言来说,每一次排序都要写一个比较函数,写出来的代码太丑,非常长,代码结构是一致,只是比较字段不一样而已,个人无法接受啊,网上搜索也没搜索到合适解决方法,所以自己想了一个解决方法来优雅排序. 比较函数: func reflectCmp(i, j interface

  • golang通过反射设置结构体变量的值

    如果需要动态设置struct变量field的情况下, 可以利用reflect来完成. 代码如下: package main import ( "fmt" "reflect" ) // 定义结构体Person type Person struct { Name string Age int } func main() { person := Person{} fmt.Println(person) // 修改前 { 0} pp := reflect.ValueOf(&

  • Go结合反射将结构体转换成Excel的过程详解

    目录 Excel中的一些概念 使用tealeg操作Excel 安装tealeg 使用tealeg新建一个表格 Go结合反射将结构体转换成Excel 反射获取每个Struct中的Tag 通过反射将结构体的值转换成map[excelTag]strucVal 利用反射将一个Silce,Array或者Struct转换成[]map[excelTag]strucVal 通过tealeg将[]map[excelTag]strucVal转换成Excel 运行测试用例验证 Excel中的一些概念 一个excel文

  • golang中使用匿名结构体的方法

    目录 转化为map 定义具名结构体 定义匿名结构体 在一些项目中, 我们会使用json 来将字符串转为结构体,但是很多时候,这种结构体只会用一次,基本上只会用于反序列化, 对于这种只用到一次的结构体, 我们可以使用匿名结构体. 在gin 接收参数的时候会非常有用, 如我们将要接收的json 参数为 { "opt": "left", "phoneinfo": [ {"device_id": 64, "sn":

  • 详解Golang利用反射reflect动态调用方法

    编程语言中反射的概念 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 每种语言的反射模型都不同,并且有些语言根本不支持反射.Golang语言实现了反射,反射机制就是在运行时动态的调用对象的方法和属性,官方自带的reflect包就是反射相关的,只要包含这个包就可以使用. 多插一句,

  • go语言通过反射创建结构体、赋值、并调用对应的操作

    我就废话不多说了,大家还是直接看代码吧~ package main import ( "fmt" "reflect" "testing" ) type Call struct { Num1 int Num2 int } func (call Call) GetSub(name string){ fmt.Printf("%v 完成了减法运算,%v - %v = %v \n", name, call.Num1, call.Num2

  • C#中使用反射获取结构体实例及思路

    复制代码 代码如下: static void Main(string[] args){    Type type = typeof(MyObject);    object obj = type.GetConstructor(Type.EmptyTypes).Invoke(null);    Console.WriteLine(obj);} class MyObject{ } 之前我一直没有发现原来结构是不可以这样实例化的 换种方式,似乎结构体使用反射无法得到其构造函数ConstructorIn

  • 利用C语言结构体实现通讯录

    本文实例为大家分享了C语言结构体实现通讯录的具体代码,供大家参考,具体内容如下 用来存储1000个人的信息的通讯录,每个人的信息包括: 姓名.性别.年龄.电话.住址 程序如下: #include<stdio.h> #include<string.h> #include<stdlib.h> struct People { char name[20]; char sex[5]; int age; char tel[15]; char addr[50]; }; //定义人的信

  • Golang 中反射的应用实例详解

    目录 引言 Golang类型设计原则 Golang 中为什么要使用反射/什么场景可以(应该)使用反射 举例场景: 反射的基本用法 反射的性能分析与优缺点 测试反射结构体初始化 测试结构体字段读取/赋值 测试结构体方法调用 优缺点 反射在 okr 中的简单应用 结论 引言 首先来一段简单的代码逻辑热身,下面的代码大家觉得应该会打印什么呢? type OKR struct { id int content string } func getOkrDetail(ctx context.Context,

随机推荐