Как получить доступ к структуре с переменной? - PullRequest
0 голосов
/ 24 ноября 2018

Я новичок в Go и столкнулся с проблемами при доступе к структуре с переменной

У меня есть эта функция decodeUser.Моя задача - проверить, присутствуют ли ключи в запросе.Так вот что я сделал.Я добавил комментарий, в котором я получил сообщение об ошибке.

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
}

На всякий случай я добавил root.User вот структура для него

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

Проблема возникает, поскольку это не такПозвольте мне получить доступ к структуре с помощью переменной, и я не могу использовать этот метод u.check.Так что в основном как мне заставить u[check] работать ?

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Вот что у меня сработало

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)
    }
}
0 голосов
/ 24 ноября 2018

Я бы посоветовал вам вручную проверять нулевые значения, поскольку кажется, что вы уже знаете поля, которые должны быть ненулевыми во время компиляции.Однако, если это не так, вот простая функция (с использованием отражения), которая будет проверять нулевые значения в структуре.

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

, которая выдаст:

[ID Username DOB]

Детская площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...