解析并验证“ key1:value1; key2:value2”字符串有效地进行结构化?

I have a "key1:value1; key2:value2" like string (string with key:value pattern concated by ;).

Now I wish to parse this string to a Go struct:

type CustomStruct struct {
   KeyName1 string `name:"key1" somevalidation:"xxx"`
   KeyName2 int    `name:"key2" somevalidation:"yyy"`
}

In the above example, the struct tag defines the name of the key in the string and can provide some validation for its corresponding value (it can set a default value if validation fails). For instance, KeyName2 is an int value, so I wish the somevalidation can check whether the KeyName2 satisfy, let's say, greater than 30 and less equal than 100.

And in another senario, I can define another struct CustomStruct2 for string like key3:value3; key4:value4;

How can I archive this kind of requirement efficiently and elegantly?

I'll assume that you can parse the data to a map[string]interface{}.

Use the reflect package to set the fields. Here's the basic function:

// 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))
        }
    }
}

This code assumes that the values in the data map are assignable to the corresponding field in the struct and that the first argument is a pointer to a struct. The code will panic if these assumptions are not true. You can protect against this by checking types and assignability using the reflect package.

playground example