1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-24 04:22:22 +00:00

fix validator

This commit is contained in:
Xargin 2018-12-21 15:02:27 +08:00
parent 22f61f1c8a
commit 2a57def713

View File

@ -10,7 +10,7 @@
## 5.4.1 重构请求校验函数
假设我们的数据已经通过某个binding库绑定到了具体的struct上。
假设我们的数据已经通过某个开源绑定库绑定到了具体的结构体上。
```go
type RegisterReq struct {
@ -42,7 +42,7 @@ func register(req RegisterReq) error{
}
```
我们用Go里成功写出了hadoken开路的箭头型代码。。这种代码一般怎么进行优化呢?
我们用Go里成功写出了波动拳开路的箭头型代码。。这种代码一般怎么进行优化呢?
很简单,在《重构》一书中已经给出了方案:[Guard Clauses](https://refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html)。
@ -73,7 +73,7 @@ func register(req RegisterReq) error{
## 5.4.2 用 validator 解放体力劳动
从设计的角度讲,我们一定会为每个请求都声明一个struct。前文中提到的校验场景我们都可以通过validator完成工作。还以前文中的struct为例。为了美观起见我们先把json tag省略掉。
从设计的角度讲,我们一定会为每个请求都声明一个结构体。前文中提到的校验场景我们都可以通过validator完成工作。还以前文中的结构体为例。为了美观起见我们先把json tag省略掉。
这里我们引入一个新的validator库
@ -131,7 +131,7 @@ fmt.Println(err)
## 5.4.3 原理
从结构上来看,每一个struct都可以看成是一棵树。假如我们有如下定义的struct
从结构上来看,每一个结构体都可以看成是一棵树。假如我们有如下定义的结构体
```go
type Nested struct {
@ -143,13 +143,13 @@ type T struct {
}
```
把这个struct画成一棵树,见*图 5-11*
把这个结构体画成一棵树,见*图 5-11*
![struct-tree](../images/ch6-04-validate-struct-tree.png)
*图 5-11 validator 树*
从字段校验的需求来讲,无论我们采用深度优先搜索还是广度优先搜索来对这棵struct树来进行遍历,都是可以的。
从字段校验的需求来讲,无论我们采用深度优先搜索还是广度优先搜索来对这棵结构体树来进行遍历,都是可以的。
我们来写一个递归的深度优先搜索方式的遍历demo
@ -235,8 +235,8 @@ func main() {
}
```
这里我们简单地对`eq=x``email`这两个tag进行了支持读者可以对这个程序进行简单的修改以查看具体的validate效果。为了演示精简掉了错误处理和复杂case的处理例如reflect.Int8/16/32/64reflect.Ptr等类型的处理如果给生产环境编写validate库的话请务必做好功能的完善和容错。
这里我们简单地对`eq=x``email`这两个tag进行了支持读者可以对这个程序进行简单的修改以查看具体的validate效果。为了演示精简掉了错误处理和复杂情况的处理例如reflect.Int8/16/32/64reflect.Ptr等类型的处理如果给生产环境编写validate库的话请务必做好功能的完善和容错。
在前一小节中介绍的validator组件在功能上要远比我们这里的demo复杂的多。但原理很简单就是用reflect对struct进行树形遍历。有心的读者这时候可能会产生一个问题我们对struct进行validate时大量使用了reflect而go的reflect在性能上不太出众,有时甚至会影响到我们程序的性能。这样的考虑确实有一些道理,但需要对struct进行大量校验的场景往往出现在Web服务这里并不一定是程序的性能瓶颈所在实际的效果还是要从pprof中做更精确的判断。
在前一小节中介绍的validator组件在功能上要远比我们这里的例子复杂的多。但原理很简单就是用反射对结构体进行树形遍历。有心的读者这时候可能会产生一个问题我们对结构体进行validate时大量使用了反射而go的反射在性能上不太出众,有时甚至会影响到我们程序的性能。这样的考虑确实有一些道理,但需要对结构体进行大量校验的场景往往出现在Web服务这里并不一定是程序的性能瓶颈所在实际的效果还是要从pprof中做更精确的判断。
如果基于反射的validator真的成为了你服务的性能瓶颈怎么办现在也有一种思路可以避免反射使用Go内置的parser对源代码进行扫描然后根据struct的定义生成校验代码。我们可以将所有需要校验的结构体放在单独的package内。这就交给读者自己去探索了。
如果基于反射的validator真的成为了你服务的性能瓶颈怎么办现在也有一种思路可以避免反射使用Go内置的Parser对源代码进行扫描然后根据结构体的定义生成校验代码。我们可以将所有需要校验的结构体放在单独的包内。这就交给读者自己去探索了。