登录
首页 >  Golang >  Go问答

检索Go中嵌套结构的所有标签

来源:stackoverflow

时间:2024-03-18 16:33:30 222浏览 收藏

在 Go 语言中,有时需要将嵌套结构的特定字段从一种语言翻译成另一种语言。为了实现这一目标,可以使用反射包中的 walkStrings 函数。该函数遍历结构体并为每个具有关联结构标记的字符串调用一个函数。该函数可以获取字段的值并使用该值调用翻译函数,将字符串翻译成所需的语言。通过使用此方法,可以轻松地翻译嵌套结构的字段,而无需手动编写代码来处理每个字段。

问题内容

我想将我的 rest 响应的某些字段从英语翻译为印地语。我几乎没有翻译文件,其中包含从英语到印地语的单词映射。我想通过字段标签提供的文件的名称。 所以我的结构看起来像这样

type myResponse struct {
        City string `translatorFile:"CityEToH"`
        State string `translatorFile:"StateEToH"`
        StationCode []string `translatorFile:"StationCodeEToH"`
        InsideStruct insideStruct
    }

    type insideStruct struct {
        trainName string `translatorFile:"TrainEToH"`
        StartingPoint string `translatorFile:"StationCodeEToH"`
        FinishPoint string `translatorFile:"StationCodeEToH"`
    }

我想编写一个通用的翻译器方法,它将接受interface{}作为输入参数,并返回一个接口(转换输入后)作为输出。我刚刚开始学习 go,并且在实现上遇到了困难。我无法创建将 fieldname 映射到相应翻译器文件名的映射类型结构。

我尝试过reflect.typeof(input),但是这样我无法获取insidestruct的标签。这只是有效负载的示例结构,我也可以有 4-5 个继承级别的结构。

有没有办法将 fieldname、tags 和 fieldvalue 放在一起。或者还有其他更好的方法来实现这个吗?


解决方案


这是一个函数,它遍历值并为每个具有关联结构标记的字符串调用函数:

func walkstrings(v reflect.value, tag reflect.structtag, fn func(reflect.value, reflect.structtag)) {
    v = reflect.indirect(v)
    switch v.kind() {
    case reflect.struct:
        t := v.type()
        for i := 0; i < t.numfield(); i++ {
            walkstrings(v.field(i), t.field(i).tag, fn)
        }
    case reflect.slice, reflect.array:
        if v.type().elem().kind() == reflect.string {
            for i := 0; i < v.len(); i++ {
                walkstrings(v.index(i), tag, fn)
            }
        }
    case reflect.string:
        fn(v, tag)
    }
}

函数 fn 可以使用 Value.String 获取字符串形式的值,并使用 Value.SetString 更改该值。使用 StructTag.Get 获取标签。一个示例函数是:

func translate(v reflect.value, tag reflect.structtag) {
    if !v.canset() {
        // unexported fields cannot be set
        return
    }
    file := tag.get("translatorfile")
    if file == "" {
        return
    }
    v.setstring(translatstringwithfile(v.string(), file)
}

使用结构体指针的reflect.value和空字符串作为标记来调用walkstrings

v := myResponse{
    City:         "mycity",
    StationCode:  []string{"code1", "code2"},
    InsideStruct: insideStruct{"trainname", "start", "finish"},
}
walkStrings(reflect.ValueOf(&v), "", translate)

Run it on the playground

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《检索Go中嵌套结构的所有标签》文章吧,也可关注golang学习网公众号了解相关技术文章。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>