如何使用变量访问结构?

I'm new to Go and I'm facing issues in accessing a struct with a variable

I have this function decodeUser. My task is to check whether the keys are present in the request. So this is what I did. I've added a comment where I got the error.

func decodeUser(r *http.Request) (root.User, []string, error) {
    var u root.User
    if r.Body == nil {
        return u, []string{}, errors.New("no request body")
    }
    decoder := json.NewDecoder(r.Body)
    checks := []string{
        "UserName",
        "FirstName",
        "LastName",
        "Email",
    }
    emptyFields := []string{}
    for _, check := range checks {
        // i'm having problem over here `u[check]` it's showing (invalid
           operation: u[check] (type root.User does not support 
           indexing))
        if u[check] == nil {
            emptyFields = append(emptyFields, check)
        }
    }
    err := decoder.Decode(&u)
    return u, emptyFields, err
}

Just in case I added root.User here's structure for it

type User struct {
    ID                   string
    Username             string
    Password             string
    FirstName            string
    LastName             string
    Email                string
    PhoneNumber          string
    PhoneNumberExtension string
    DOB                  time.Time
    AboutMe              string
}

The problem occurs as it doesn't allow me to access struct by a variable and I can't use this method which is u.check. So basically how should I make u[check] work?

This is what worked for me

for _, check := range checks {
    temp := reflect.Indirect(reflect.ValueOf(&u))
    fieldValue := temp.FieldByName(string(check))
    if (fieldValue.Type().String() == "string" && fieldValue.Len() == 0) || (fieldValue.Type().String() != "string" && fieldValue.IsNil()) {
        fmt.Println("EMPTY->", check)
        emptyFields = append(emptyFields, check)
    }
}

I would suggest you manually check for zero values since it seems that you already know the fields that needs to be non-zero at compile time. However, if that is not the case, here is a simple function (using reflection) that will check for zero values in a struct.

func zeroFields(v interface{}, fields ...string) []string {

    val := reflect.Indirect(reflect.ValueOf(v))
    if val.Kind() != reflect.Struct {
        return nil
    }

    var zeroes []string

    for _, name := range fields {

        field := val.FieldByName(name)

        if !field.IsValid() {
            continue
        }

        zero := reflect.Zero(field.Type())
        // check for zero value
        if reflect.DeepEqual(zero.Interface(), field.Interface()) {
            zeroes = append(zeroes, name)
        }

    }

    return zeroes
}

func main() {

    x := User{
        Email: "not@nil",
    }

    fmt.Println(zeroFields(&x, "ID", "Username", "Email", "Something", "DOB"))
}

Which would output:

[ID Username DOB]

Playground