何时该用assert

缘起

今天看<重构>这本书中看到assert的部分,说到使用它很有必要,又说不能够滥用,只有确定它一定发生的地方去使用.这下我就蒙了,到底怎么样的算是这种场景呢?

搜索

从知乎上搜到了一些有用的说法:https://www.zhihu.com/question/24461924

1.assert是用来处理程序员自己的错误,异常是处理用户或者环境的错误.(这里从别处搜到了一个assert的使用场景:用于private函数中判断参数,因为这个函数只能是程序员自己能够调用的,可以避免传入有问题的参数)

2.应用场景举例:

  • 检查参数有效性
//举例:
auto ptr3 = make_unique<int>(42);               // 工厂函数创建智能指针
assert(ptr3 && *ptr3 == 42);
  • 检查数组越界
  • switch/if控制流中的can't reach here放一个
  • 不要free空指针

3.契约式编程对这一块有更准确的解释.assert用于对前条件的检查,异常用于对后条件的检查.举个例子,strcpy()函数,在执行前对参数的检查就是属于前条件,包括第一个参数要以'\0'结尾,第二个参数的长度要大于第一个参数的长度;而后条件是判断操作后第二个参数的内容是否和第一个参数一样.只不过处于性能的考虑strcpy()的实现没有使用这些.

 

那是不是要对函数参数进行检查的前条件就可以用assert呢?我从极客时间的一篇更详细的文章:https://time.geekbang.org/column/article/106098

assert很重要一点时,它可以在release模式下关闭掉(当然也可以不关闭),所以使用时要注意这个.

作者举了个例子,一个售货系统只有管理员才能够删除上架的课程,如果只用assert实现,可能会写成这样:

def delete_course(user, course):
    assert is_admin(user), "only admin can delete"
    assert is_exist(course), "the course is not exist"
    delete(course)

这样当把assert给关掉时,会造成只执行delete操作,即任何权限的人都可以删除课程,无论课程是否存在. 此处影响到了业务的逻辑.

像这种情况就不能够只是使用assert,可以考虑采用异常来解决:

def delete_course(user, course):
    if not is_admin(user):
        raise Exception("only admin can delete")
    if not is_exist(course):
        raise  Exception("the course is not exist")
    delete(course)

 

另外一个打开文件的例子:

def file_process(file):
    assert is_exist(file), "file is not exist"
    with open(file) as f:
        ...

这个会存在一个问题,当文件不存在时,open会报IOError,并且即使文件存在打开时也可能会出现异常,因此用异常去处理,更合适:

def file_process(file):
    try:
        with open(file) as f:
            ...
    except Exception as e:
        ...

这种情况属于运行时错误(一般程序错误分为语法错误,运行时错误,逻辑错误)不适合只采用assert,适合采用异常进行处理.

 

总结

何时使用:

1.assert表示的语句用于一定为真的情况,常用于前条件判断,用来反映程序员的错误,比如检查参数的有效性.

2.如果去掉assert语句,会影响业务逻辑,则不应该使用assert.

3.对于运行时错误,不要使用asset,应选择使用异常.

 

作用:

1.有时断言可以帮助程序员找到bug,因为它离出错点很近.

2.但更多时候,断言的价值在于:帮助程序员理解代码正确运行时的必要条件.

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingLife99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值