0

0

如何通过反射传递 Type 来调用 Go 中的泛型函数

王林

王林

发布时间:2024-02-05 22:21:03

|

1372人浏览过

|

来源于stackoverflow

转载

如何通过反射传递 type 来调用 go 中的泛型函数

问题内容

我有一个 Go 应用程序,可以接收同一 API 的不同 JSON 响应,因此我尝试编写一个自定义解组器,它将尝试处理每个可能的 JSON 响应,直到找到正确的响应。

为此,我创建了一个通用函数来解组 JSON,并且我想使用从反射获得的类型来调用它。

例如:

package main

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

type JSONHandler struct{}

func (handler *JSONHandler) Unmarshal(data []byte) error {
    t := reflect.TypeOf(*handler)

    for i := 0; i < t.NumField(); i++ {
        fieldType := t.Field(i)

        fmt.Printf("Trying to unmarshal: %s\n", fieldType.Name)
        result, err := unmarshal[fieldType](data) // fieldType (variable of type reflect.StructField) is not a typecompiler (NotAType)

        if err == nil {
            fmt.Printf("result: %s\n", result)
            break
        }
    }

    return nil
}

func unmarshal[T interface{}](data []byte) (*T, error) {
    obj := new(T)

    reader := bytes.NewReader(data)
    decoder := json.NewDecoder(reader)
    decoder.DisallowUnknownFields()

    err := decoder.Decode(obj)
    if err != nil {
        return nil, err
    }
    return obj, nil
}

type User struct {
    Username *string `json:"username,omitempty"`
    Password *string `json:"password,omitempty"`
}

type UserError struct {
    Error *string `json:"error,omitempty"`
    Code  *int    `json:"code,omitempty"`
}

type UserOrError struct {
    User      *User
    UserError *UserError
    JSONHandler
}

var userJson = `{ "username": "[email protected]", "password": "password" }`

func main() {
    user := new(UserOrError)
    result := user.Unmarshal([]byte(userJson)) // { User: something, UserError: nil }
}

但是,Go 编译器给了我这个错误:fieldType (reflect.StructField 类型的变量) 不是类型编译器 (NotAType)

有没有办法将反射参数传递给泛型函数?

微信 WeLM
微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

下载

正确答案


这个问题超出了 Go 通用功能的范围。

使用 reflect.New 创建一个给定该值的reflect.Type的值。 p>

Go 没有继承。问题中的 Unmarshal 方法对没有字段的类型进行操作。通过将“处理程序”传递给普通函数来修复。

// Unmarshal unmarshals data to each field type in handler
// and returns the first successful result. The handler argument
// must be a pointer to a struct.
func Unmarshal(handler any, data []byte) (any, error) {
    t := reflect.TypeOf(handler).Elem()
    for i := 0; i < t.NumField(); i++ {
        fieldType := t.Field(i)
        v := reflect.New(fieldType.Type)
        decoder := json.NewDecoder(bytes.NewReader(data))
        decoder.DisallowUnknownFields()
        err := decoder.Decode(v.Interface())
        if err == nil {
            return v.Elem().Interface(), err
        }
    }
    return nil, errors.New("no matching type")
}

像这样使用 Marshal 函数:

type UserOrError struct {
    User      *User
    UserError *UserError
}

var userJson = `{ "username": "[email protected]", "password": "password" }`

result, err := Unmarshal(&UserOrError{}, []byte(userJson)) // { User: something, UserError: nil }
fmt.Printf("err=%v, result=%#v\n", err, result)

https://www.php.cn/link/c76e4b2fa54f8506719a5c0dc14c2eb9

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

411

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

532

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

309

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1969

2024.08.16

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

61

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

31

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

72

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

20

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号