自学内容网 自学内容网

go语言动态返回所需字段

package main

import (
"encoding/json"
"errors"
"fmt"
"reflect"
)

func JsonPrint(student interface{}) interface{} {
jsonData, err := json.MarshalIndent(student, "", "  ")
if err != nil {
fmt.Println("JSON 编码失败:", err)
return nil
}
return string(jsonData)
}

type Student struct {
AAA string
BBB string
CCC string
}

func main() {
// 传入返回值字符串
fields := []string{"CCC"}

// 创建切片数据集
student := []Student{
{AAA: "1", BBB: "John Doe", CCC: "20"},
{AAA: "2", BBB: "Jane Doe", CCC: "22"},
{AAA: "3", BBB: "Mike Smith", CCC: "23"},
}
data, _ := FormatConversion(student, fields)
fmt.Println("切片返回到前端的数据: ", data)

// 创建单个数据集
student2 := Student{
AAA: "John Doe",
BBB: "20",
CCC: "Male",
}
data2, _ := FormatConversion(student2, fields)
fmt.Println("结构体返回到前端的数据: ", data2)
}

// 不用看后面那两个函数,只需要调用这一个函数即可
// 这个函数引用了下面两个函数的逻辑
// 当前函数值用于判断传入的参数是结构体还是切片,然后执行后面对应的函数处理相关逻辑
func FormatConversion(base interface{}, fields []string) (interface{}, error) {
value := reflect.ValueOf(base)

switch value.Kind() {
case reflect.Struct:
// 传入参数为结构体,对切片进行处理
// 参数一为传入的结构体,参数二为所需要返回的字段
dynamicStruct, err := createDynamicStruct(base, fields)
if err != nil {
fmt.Println(err)
return nil, err
}
// 打印返回的数据
fmt.Println("打印转换后的数据" , JsonPrint(dynamicStruct))
return dynamicStruct, nil
case reflect.Slice:
// 传入参数为切片,对切片进行处理
// 参数一为传入的切片,参数二为所需要返回的字段
dynamicStruct, err := createDynamicStructsFromSlice(base, fields)
if err != nil {
fmt.Println(err)
return nil, err
}
// 打印转换后的数据
fmt.Println("打印转换后的数据" , JsonPrint(dynamicStruct))
return dynamicStruct, nil
default:
fmt.Println("未知类型") // 既不是结构体也不是切片
return nil, errors.New("参数一传入格式有误,请传入结构体或者切片")
}
}

// 传入一个结构体和字符串数组,返回一个动态结构体
// 同时在处理切片时也会用到该函数
func createDynamicStruct(base interface{}, fields []string) (interface{}, error) {
baseType := reflect.TypeOf(base)
if baseType.Kind() != reflect.Struct {
return nil, fmt.Errorf("expected a struct, got %s", baseType.Kind())
}

fieldValues := make([]reflect.Value, 0, len(fields))
fieldNames := make([]reflect.StructField, 0, len(fields))

for _, fieldName := range fields {
field, found := baseType.FieldByName(fieldName)
if !found {
return nil, fmt.Errorf("field %s not found in struct", fieldName)
}
fieldValues = append(fieldValues, reflect.ValueOf(base).FieldByName(fieldName))
fieldNames = append(fieldNames, reflect.StructField{
Name: fieldName,
Type: field.Type,
Tag:  field.Tag,
})
}

// 创建一个动态类型,包含所需的字段
dynamicType := reflect.StructOf(fieldNames)
dynamicValue := reflect.New(dynamicType).Elem()

// 设置动态结构体的字段值
for i, fieldValue := range fieldValues {
dynamicValue.Field(i).Set(fieldValue)
}

return dynamicValue.Interface(), nil
}

// 传入一个切片和字符串数组,返回一个动态结构体切片
func createDynamicStructsFromSlice(baseSlice interface{}, fields []string) ([]interface{}, error) {
sliceValue := reflect.ValueOf(baseSlice)
if sliceValue.Kind() != reflect.Slice {
return nil, fmt.Errorf("expected a slice, got %s", sliceValue.Kind())
}

baseElemType := sliceValue.Type().Elem()
if baseElemType.Kind() != reflect.Struct {
return nil, fmt.Errorf("slice elements are not structs")
}

var dynamicSlice []interface{}
for i := 0; i < sliceValue.Len(); i++ {
elem := sliceValue.Index(i)
dynamicStruct, err := createDynamicStruct(elem.Interface(), fields)
if err != nil {
return nil, err
}
dynamicSlice = append(dynamicSlice, dynamicStruct)
}

return dynamicSlice, nil
}

上面代码可以直接放到main.go运行一下,运行结果如下:

在这里插入图片描述


原文地址:https://blog.csdn.net/weixin_68658847/article/details/142556886

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!