解析并验证“ key1:value1; key2:value2”字符串以有效地执行struct?

时间:2018-06-29 21:11:46

标签: go

我有一个像字符串一样的“ key1:value1; key2:value2”(带有key:value的{​​{1}}模式的字符串)。

现在我希望将此字符串解析为Go结构:

;

在上面的示例中,struct标记定义了字符串中键的名称,并且可以为其相应的值提供一些验证(如果验证失败,则可以设置默认值)。例如,type CustomStruct struct { KeyName1 string `name:"key1" somevalidation:"xxx"` KeyName2 int `name:"key2" somevalidation:"yyy"` } 是一个KeyName2的值,所以我希望int可以检查somevalidation是否满足大于等于30且小于等于100的要求。 / p>

在另一种方法中,我可以为KeyName2这样的字符串定义另一个结构CustomStruct2

如何有效,优雅地归档这种要求?

1 个答案:

答案 0 :(得分:2)

我假设您可以将数据解析到map [string] interface {}。

使用reflect包设置字段。基本功能如下:

// set sets fields in struct pointed to by pv to values in data.
func set(pv interface{}, data map[string]interface{}) {
    // pv is assumed to be pointer to a struct
    s := reflect.ValueOf(pv).Elem()

    // Loop through fields
    t := s.Type()
    for i := 0; i < t.NumField(); i++ {

        // Set field if there's a data value for the field.
        f := t.Field(i)
        if d, ok := data[f.Tag.Get("name")]; ok {
            s.Field(i).Set(reflect.ValueOf(d))
        }
    }
}

此代码假定数据映射中的值可分配给结构中的相应字段,并且第一个参数是指向结构的指针。如果这些假设不成立,则代码将感到恐慌。您可以通过使用反射包检查类型和可分配性来防止这种情况。

playground example