您的位置 首页 golang

如何优雅的写校验函数

有的时候,为了检查入参,会有很多项需要检查,如果一个一个if-else的去判断,会显得很low,先看一个比较丑的写法:

func checkQeuryParam(c *condition) bool {    if c.offset > 100000 {        return false    }    if c.limit > 100 {        return false    }    if c.timebegin != "" {        zone := time.FixedZone("CST", 8*3600)        t, err := time.ParseInLocation("2006-01-02T15:04:05.000+0800", c.timebegin, zone)        if err != nil {            aialog.Error.Printf("Query time %s is invalid.\n", c.timebegin)            return false        }        c.timebegin = t.Format("2006-01-02T15:04:05.000+0800")    }    //ip no check    //come_from no check    //event    if c.event != "" {        if c.event != "added" && c.event != "modified" && c.event != "deleted" {            return false        }    }    //ruleid    if c.ruleid != "" {        id, err := strconv.Atoi(c.ruleid)        if err != nil {            return false        }        //id range, temporary        if id < 0 || id > 1000000 {            return false        }    }    if c.rulelevel != "" {        level, err := strconv.Atoi(c.rulelevel)        if err != nil {            return false        }        //level range 0-16        if level < 0 || level > 15 {            return false        }    }    if c.agentid != "" {        if len(c.agentid) > 64 {            return false        }    }    //order    if c.order != "" {        if c.order != "desc" && c.order != "asc" {            return false        }    }    return true}

1、易读性很差
2、修改麻烦
3、不易扩展
4、打印失败信息麻烦,需要每个异常分支添加

调整为如下方式:

func (c *condition)checkOffset() bool {    if c.offset > 100000 {        return false    }    return true}func (c *condition)checkLimit() bool {    if c.limit > 100 {        return false    }    return true}func (c *condition)checkTime() bool {    if c.timebegin != "" {        zone := time.FixedZone("CST", 8*3600)        t, err := time.ParseInLocation("2006-01-02T15:04:05.000+0800", c.timebegin, zone)        if err != nil {            aialog.Error.Printf("Query time %s is invalid.\n", c.timebegin)            return false        }        c.timebegin = t.Format("2006-01-02T15:04:05.000+0800")    }    return true}func (c *condition)checkEvent() bool {    if c.event != "" {        if c.event != "added" && c.event != "modified" && c.event != "deleted" {            return false        }    }    return true}func (c *condition)checkRuleid() bool {    if c.ruleid != "" {        id, err := strconv.Atoi(c.ruleid)        if err != nil {            return false        }        //id range, temporary        if id < 0 || id > 1000000 {            return false        }    }    return true}func (c *condition)checkRulelevel() bool {    if c.rulelevel != "" {        level, err := strconv.Atoi(c.rulelevel)        if err != nil {            return false        }        //level range 0-16        if level < 0 || level > 15 {            return false        }    }    return true}func (c *condition)checkAgentid() bool {    if c.agentid != "" {        if len(c.agentid) > 64 {            return false        }    }    return true}func (c *condition)checkOrder() bool {    if c.order != "" {        if c.order != "desc" && c.order != "asc" {            return false        }    }    return true}func checkQeuryParam(c *condition) bool {    checks := []struct{        name string        fn   func() bool    }{        {"check offset", c.checkOffset},        {"check limit", c.checkLimit},        {"check time", c.checkTime},        {"check event", c.checkEvent},        {"check rule id", c.checkRuleid},        {"check rule level", c.checkRulelevel},        {"check agent id", c.checkAgentid},        {"check order", c.checkOrder},    }    for _, check := range checks {        if !check.fn() {            aialog.Error.Printf("%s failed.\n", check.name)            return false        }    }    return true}

1、条理清晰,易读性好
2、增加判断时,直接新增函数
3、打印失败信息也比较方便,且新增判断也不用新增打印

注:
对于函数名作为参数时,如果是传的方法,需要连对象一起传入。
如上的fn,传入时为c.checkXXX,c为这个方法的实际调用对象。


文章来源:智云一二三科技

文章标题:如何优雅的写校验函数

文章地址:https://www.zhihuclub.com/6917.shtml

关于作者: 智云科技

热门文章

网站地图