0

0

如何使用反射提取类型参数

王林

王林

发布时间:2024-02-12 17:24:05

|

687人浏览过

|

来源于stackoverflow

转载

如何使用反射提取类型参数

问题内容

上下文:我正在编写一个通用自动映射器,它采用两种类型的结构,检查所述结构的每个字段是否有给定的标签,然后将值从源结构复制到目标结构,假设它们具有匹配的标签和类型。每当结构字段是另一个(嵌套)结构时,我希望自动映射器函数执行递归调用,自动映射到兔子洞。

问题:我只能传递根结构的具体类型。一旦我进入使用反射的通用函数,尝试提取嵌套的结构类型似乎是不可能的。 虽然我可以传递 value.interface() 作为参数,但我仍然需要传递类型参数。

这里有一些简化的代码来显示问题。

type Alpha struct {
    Nested Beta `automap:"nested"`
}

type Beta struct {
    Info string `automap:"info"`
}

type Foo struct {
    Nested Bar `automap:"nested"`
}

type Bar struct {
    Info string `automap:"info"`
}

func TestAutoMap(t *testing.T) {

    b := Beta{Info: "Hello from Beta!"}
    a := Alpha{Nested: b}

    f, err := AutoMap[Alpha, Foo](a)
    if err != nil {
        fmt.Println(err)
        t.Fail()
    }
    fmt.Println("f.nested.info:", f.Nested.Info)
}

func AutoMap[S, T any](source S) (target T, err error) {

    targetStruct := reflect.ValueOf(&target).Elem()
    sourceStruct := reflect.ValueOf(&source).Elem()

    // .Type and .Kind directly did not work.
    nestedSourceType := ??? // I want this to be type Beta.
    nestedTargetType := ??? // I want this to be type Bar.

    sourceInterface := sourceStruct.Interface()

    t, err := AutoMap[nestedSourceType, nestedTargetType](sourceInterface)
    if err != nil {
        return target, err
    }
    target = t

    return target, nil
}

解决方法

按照@mkopriva的建议,我想分享一个简单的解决方案来解决我遇到的问题。 p>

请随意纠正或改进它,但请记住,我故意不包括下面的各种检查和断言。

CA.LA
CA.LA

第一款时尚产品在线设计平台,服装设计系统

下载

(go playground 示例)

type Alpha struct {
    NestedOnce Beta
}

type Beta struct {
    NestedTwice Gamma
}

type Gamma struct {
    Info string
}

type Foo struct {
    NestedOnce Bar
}

type Bar struct {
    NestedTwice Baz
}

type Baz struct {
    Info string
}

func TestAutoMap(t *testing.T) {

    g := Gamma{"Hello from Gamma!"}
    b := Beta{g}
    a := Alpha{b}

    f, err := AutoMap[Foo](a)
    if err != nil {
        fmt.Println(err)
        t.Fail()
    } else {
        fmt.Println("Foo.NestedOnce.NestedTwice.Info:", f.NestedOnce.NestedTwice.Info)
    }
}

func AutoMap[T any](source any) (target T, err error) {

    // Peel off 'any' from the function parameter type.
    sourceStruct := reflect.ValueOf(&source).Elem().Elem()

    targetStruct := reflect.ValueOf(&target).Elem()

    err = autoMap(sourceStruct, targetStruct)

    return target, err
}

func autoMap(s, t reflect.Value) error {

    sourceField := s.Field(0)
    targetField := t.Field(0)

    if sourceField.Kind() == reflect.Struct {
        err := autoMap(sourceField, targetField)
        if err != nil {
            return err
        }
        return nil
    }

    targetField.Set(sourceField)

    return nil
}

相关专题

更多
go中interface用法
go中interface用法

本专题整合了go语言中int相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.09.10

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

20

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

5

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

26

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

2

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

7

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

3

2026.01.15

php图片上传教程汇总
php图片上传教程汇总

本专题整合了php图片上传相关教程,阅读专题下面的文章了解更多详细教程。

2

2026.01.15

phpstorm相关教程大全
phpstorm相关教程大全

本专题整合了phpstorm相关教程汇总,阅读专题下面的文章了解更多详细内容。

4

2026.01.15

热门下载

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

精品课程

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

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