检查POST参数的更好方法是什么?

时间:2016-09-05 10:32:51

标签: validation go struct conditional-statements

我目前正致力于使用Golang设置API。我正在制作注册路线,我需要检查我var students = [{ name: "Mike", track: "track-a", achievements: 23, points: 400, }, { name: "james", track: "track-a", achievements: 2, points: 21, }, ] students.forEach(myFunction); function myFunction(item, index) { for (var key in item) { console.log(item[key]) } }中是否填写了所有内容。所以现在我使用非常长条件。我确定必须有更高效/更优雅的解决方案,但我不知道怎么找不到它们。

以下是代码段:

SignupModel

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

您可以创建一个使用反射(reflect包)的一般辅助函数来检查结构的所有字段:

func check(s interface{}) error {
    v := reflect.ValueOf(s)
    for i := v.NumField() - 1; i >= 0; i-- {
        if v.Field(i).Interface() == "" {
            return fmt.Errorf("Field %s is empty!", v.Type().Field(i).Name)
        }
    }
    return nil
}

使用它:

fmt.Println(check(SignupModel{"a", "b", "c", "d", "e", "f", "g"}))
fmt.Println(check(SignupModel{}))

输出(在Go Playground上尝试):

<nil>
Field Picture is empty!

<强>改进:

上述check()函数适用于所有类型,不仅适用于SignupModel,但目前只有string类型的字段处理。如果要支持其他字段类型,可以改进它。

这是一个改进的版本,它也处理其他类型的字段,如果传递的值是指向结构的指针(只是解引它),它也会处理。如果传递非struct值,则返回错误:

func check(s interface{}) error {
    v := reflect.Indirect(reflect.ValueOf(s))
    if v.Kind() != reflect.Struct {
        return fmt.Errorf("Not struct!")
    }
    v2 := reflect.Zero(v.Type())
    for i := v.NumField() - 1; i >= 0; i-- {
        if v.Field(i).Interface() == v2.Field(i).Interface() {
            return fmt.Errorf("Field %s is empty!", v.Type().Field(i).Name)
        }
    }
    return nil
}

测试它:

fmt.Println(check(&struct{ I int }{1}))
fmt.Println(check(struct{ I int }{}))
fmt.Println(check(struct { I int; S string }{1, "a"}))
fmt.Println(check(&struct { I int; S string }{}))
fmt.Println(check("I'm a string"))

输出(在Go Playground上尝试):

<nil>
Field I is empty!
<nil>
Field S is empty!
Not struct!

最终说明:

上述解决方案使用的反射总是比直接代码慢(您试图缩短的代码)。但是,由于我们正在讨论HTTP POST请求,因此性能差异可以忽略不计(因为HTTP POST请求可能需要数百毫秒,而此{{1}使用check()类型的值进行调用时,函数需要半微秒

如果您想要混合代码的速度和灵活性,一个选项是创建一个生成器(SignupModel,阅读博客文章:Generating code)生成唯一的go generate辅助函数,每个函数对应一个不同的结构类型,不进行反射操作(使用直接字段值比较)。