From fee019b9e182544403cd8d175d989050c0bb6eea Mon Sep 17 00:00:00 2001 From: Xargin Date: Fri, 2 Mar 2018 19:37:20 +0800 Subject: [PATCH] update validator --- ch6-web/ch6-04-validator.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ch6-web/ch6-04-validator.md b/ch6-web/ch6-04-validator.md index 48b7932..0fe67fe 100644 --- a/ch6-web/ch6-04-validator.md +++ b/ch6-web/ch6-04-validator.md @@ -200,6 +200,8 @@ func validate(v interface{}) (bool, string) { } } case reflect.Struct: + // 如果有内嵌的 struct,那么深度优先遍历 + // 就是一个递归过程 valInter := fieldVal.Interface() nestedResult := validate(valInter) if nestedResult == false { @@ -219,8 +221,8 @@ func main() { ``` -这里我们简单地对 eq=x 和 email 这两个 tag 进行了支持,读者可以对这个程序进行简单的修改以查看具体的 validate 效果。 +这里我们简单地对 eq=x 和 email 这两个 tag 进行了支持,读者可以对这个程序进行简单的修改以查看具体的 validate 效果。为了演示精简掉了错误处理和复杂 case 的处理,例如 reflect.Int8/16/32/64,reflect.Ptr 等类型的处理,如果给生产环境编写 validate 库的话,请务必做好功能的完善和容错。 -在前一小节中介绍的 validator 组件在功能上要远比我们的 demo 复杂的多。但原理很简单,就是用 reflect 对 struct 进行树形遍历。有心的读者这时候可能会产生一个问题,我们对 struct 进行 validate 时大量使用了 reflect,而 go 的 reflect 在性能上不太出众,有时甚至会影响到我们程序的性能。这样的考虑确实有一些道理,但需要对 struct 进行大量校验的场景往往出现在 web 服务,这里并不一定是程序的性能瓶颈所在,实际的效果还是要从 pprof 中做更精确的判断。 +在前一小节中介绍的 validator 组件在功能上要远比我们这里的 demo 复杂的多。但原理很简单,就是用 reflect 对 struct 进行树形遍历。有心的读者这时候可能会产生一个问题,我们对 struct 进行 validate 时大量使用了 reflect,而 go 的 reflect 在性能上不太出众,有时甚至会影响到我们程序的性能。这样的考虑确实有一些道理,但需要对 struct 进行大量校验的场景往往出现在 web 服务,这里并不一定是程序的性能瓶颈所在,实际的效果还是要从 pprof 中做更精确的判断。 如果基于反射的 validator 真的成为了你服务的性能瓶颈怎么办?现在也有一种思路可以避免反射:使用 golang 内置的 parser 对源代码进行扫描,然后根据 struct 的定义生成校验代码。我们可以将所有需要校验的结构体放在单独的 package 内。这就交给读者自己去探索了。