我目前正致力于使用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
提前感谢您的帮助。
答案 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
辅助函数,每个函数对应一个不同的结构类型,不进行反射操作(使用直接字段值比较)。