Golang 动态访问结构属性

标签 go struct

我正在为 golang 中的 json 处理器编写一个快速 ssh 配置。我有以下结构:

type SshConfig struct {
    Host string
    Port string
    User string
    LocalForward string
    ...
}

我目前正在遍历我的 ssh 配置文件的每一行,并在空格上拆分行并检查要更新的属性。

if split[0] == "Port" {
    sshConfig.Port = strings.Join(split[1:], " ")
}

有没有办法检查属性是否存在,然后动态设置它?

最佳答案

使用 reflect按名称设置字段的包:

// setField sets field of v with given name to given value.
func setField(v interface{}, name string, value string) error {
    // v must be a pointer to a struct
    rv := reflect.ValueOf(v)
    if rv.Kind() != reflect.Ptr || rv.Elem().Kind() != reflect.Struct {
        return errors.New("v must be pointer to struct")
    }

    // Dereference pointer
    rv = rv.Elem()

    // Lookup field by name
    fv := rv.FieldByName(name)
    if !fv.IsValid() {
        return fmt.Errorf("not a field name: %s", name)
    }

    // Field must be exported
    if !fv.CanSet() {
        return fmt.Errorf("cannot set field %s", name)
    }

    // We expect a string field
    if fv.Kind() != reflect.String {
        return fmt.Errorf("%s is not a string field", name)
    }

    // Set the value
    fv.SetString(value)
    return nil
}

这样调用它:

var config SshConfig

...

err := setField(&config, split[0], strings.Join(split[1:], " "))
if err != nil {
   // handle error
}

playground example

关于Golang 动态访问结构属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47961245/

相关文章:

xml.Unmarshal 错误 : expected element type <dict> but have <plist>

go - 这个 "common idiom"是如何工作的?

go - 是否可以在模板内的结构中明智地呈现 url.URL 值?

c - 结构中的链表

c++ - 使用 char* 构建动态结构的更好方法?

go - go CLI解决方案最佳实践

go - 如何在Visual Studio代码中允许“vendor ”文件夹支持

在 C 中创建具有 2 个结构的单向链表

python - 标准库中的 "common"模块是什么?

c - 结构体中的多维动态数组,大小由 C 中同一结构体中的 int 定义