如何使用变量访问结构?

时间:2018-11-24 10:30:31

标签: go struct

我是Go语言的新手,在访问带有变量的结构时遇到问题

我具有此功能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 } 。我的任务是检查请求中是否存在密钥。这就是我所做的。我在出现错误的地方添加了评论。

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

以防万一我添加了root用户是这里的结构

u.check

发生问题是因为它不允许我通过变量访问struct,并且我不能使用u[check]这种方法。因此,基本上我应该如何使for (int i = 0; i < 10; i++) { Console.WriteLine(i + "-Completed"); string xText = $@"INSERT INTO users (login, unick, password, age, summary, create_date, version) VALUES('admin{i}', 'admin{i}', 'admin{i}', 20, 'admin{i}', today(), 1);"; var command = connection.CreateCommand(); command.CommandText = xText; command.Parameters.Add(new ClickHouseParameter { ParameterName = "bulk", Value = list }); command.ExecuteNonQuery(); } 工作

2 个答案:

答案 0 :(得分:0)

我建议您手动检查零值,因为似乎您已经知道在编译时需要非零的字段。但是,如果不是这种情况,这是一个简单的函数(使用反射),它将检查结构中的零值。

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]

Playground

答案 1 :(得分:0)

这是对我有用的

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