【问题标题】:Accessing values through bracket notation with a variable in bracket after looping through struct for field names在遍历字段名称的结构后,通过括号表示法访问值,括号中的变量
【发布时间】:2018-11-30 02:07:05
【问题描述】:

我有 2 个 JSON 文件,一个包含用户,另一个包含电子邮件模板

我正在遍历电子邮件模板中的代码,当有一个键作为值时,像这样:

"keyToFind": "Username"

然后我想在另一个 JSON 文件中获取 Username 的值:

"Username": "ssmith"

KeyToFind 可以是几个不同的东西,比如密码或组,我想避免编写特定的 if 语句

我正在尝试在我的循环中执行此操作,但似乎我不能在括号表示法中使用变量

for _, emailElements := range emailTemplates.EmailSpecification {
                for _, fieldName := range structs.Names(&User{}) {
                    if emailElements.KeyToFind == fieldName {
                        EmailBody.WriteString(user[fieldName])
                    }
                }

上面试图做的是遍历电子邮件模板中的元素,然后是用户结构中的字段;其中KeyToFind类型的模板JSON文件中的emailElement被获取,这与结构中的字段名称相同;查找 KeyToFind 的用户

我可以在 Python 中毫无问题地做到这一点

如何重写第 4 行以在 Go 中工作? --> 用户[字段名]

我得到的错误是:

user[fieldName] (type User does not support indexing)

但如果我再次将第 4 行写到这里:

user.Username

它可以正常工作,但这显然仅适用于用户名,它们可以是 KeyToFind 中的值的密码或组

以下是 JSON 文件:

电子邮件模板:

    "emailName": "customer",
    "emailSpecification": [
        {
            "emailSubject": "Hi"
        },
        {
            "text": "Username: "
        },
        {
            "keyToFind": "Username"
        }
]

我想获取 KeyToFind 的值并在用户文件中搜索属性并从该属性返回值

用户文件:

[
{
    "UserType": "customer",
    "Username": "ssmith",
    "Password": "sophie"
}
]

【问题讨论】:

  • 是的,您使用选择器(.)来访问您已经展示的结构字段。你知道你想要的结构的字段,所以我不确定你在问什么。
  • 你不能改变 Go 中平方符号的行为。您可以做的是使用像 jsonparser 这样的库或其他一些好的、高性能的 json 库而不是 encoding/json 并使用它而不是反射。
  • 我希望能够在点之后动态选择以下字段,因此它来自变量而不是硬编码。这意味着我可以根据我在另一个 JSON 文件中编写的配置从一个 JSON 文件中查找值。
  • 您不能动态更改静态类型/编译语言中的代码。您可以通过反射轻松地做到这一点,但这很少是您应该做的。您能否更好地解释为什么您认为您需要“在点后动态选择以下字段”?
  • @MassiveOwl 为什么不提供代码的更多细节?

标签: go


【解决方案1】:

我是通过将 User 结构转换为地图来获得它的,一旦它是地图,您就可以使用括号表示法内部带有点表示法

在我的上下文中,我必须转换为字符串以传递给缓冲区所需的 WriteString 函数

这是最终版本:

for _, emailElements := range emailTemplates.EmailSpecification {
                for _, fieldName := range structs.Names(&User{}) {
                    if emailElements.KeyToFind == fieldName {
                        EmailBody.WriteString(structs.Map(user)[emailElements.KeyToFind].(string))
                    }
                }
}

它正在使用包:

"github.com/fatih/structs"

【讨论】:

  • 附带说明:您使用的包依赖于下面的反射。我建议您不要一开始就使用 User 类型,而只使用原始地图。它的表现会好得多
  • 谢谢你的建议,会做的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多