编程中的卫语句

什么是卫语句在《阿里巴巴Java开发手册》中提到,多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。那么,什么是卫语句呢?在中文维基百科中是这样介绍的在计算机程序设计中,卫(guard)是布尔表达式,其结果必须为真,程序才能执行下去。卫语句(guardcode或guardclause)用于检查先决条件。卫语句的用途,例如:引用(reference)使用前检查是否为空引用;处置模式使用一个布尔域,使得释放资源操作成为幂等运算,即多次释放资源等效于只释放一次。卫语句可用于子进程的提前

大家好,又见面了,我是你们的朋友全栈君。

什么是卫语句

在《阿里巴巴Java开发手册》中提到,多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。

那么,什么是卫语句呢?

在中文维基百科中是这样介绍的

在计算机程序设计中,卫(guard)是布尔表达式,其结果必须为真,程序才能执行下去。卫语句(guard code或guard clause)用于检查先决条件。卫语句的用途,例如:
引用(reference)使用前检查是否为空引用;
处置模式使用一个布尔域,使得释放资源操作成为幂等运算,即多次释放资源等效于只释放一次。
卫语句可用于子进程的提前退出(early exit),这是结构化程序设计的一种常见偏离,可删除一层嵌套使得代码更扁平:把if guard { … }替代为:if not guard: return; …

而在英文维基百科中有这样一段话

Regardless of which programming language is used, guard clause, guard code, or guard statement, is a check of integrity preconditions used to avoid errors during execution.

重点关注avoid errors during execution,这里体现了guard是指什么,可以理解为代码中的保卫者,起到检查边界,保卫代码的作用。介绍有点绕人,但可以看出来卫语句并非Java所特有,这更像一种编程思想,我们看看两个例子吧。

例子

double GetPayAmount()
{ 
   
    double result;
    if (IsDead())
    { 
   
        result = DeadAmount();
    }
	else
    { 
   
       if (IsSeparated())
       { 
   
           result = SeparatedAmount();
       }
       else
       { 
   
           if (IsRetired())
           { 
   
               result = RetiredPayAmount();
           }
           else
           { 
   
               result = NormalPayAmount();
           }
       }
   }
   return result;
}

以上代码已经尽力做到简洁和清晰了,但是如果我们使用卫语句,将带来另一种效果:

double getPayAmount()
{ 
   
    if (isDead())
    { 
   
        return deadPayAmount();
    }
    if (isSeparated())
    { 
   
        return separatedPayAmount();
    }
    if (isRetired())
    { 
   
        return retiredPayAmount();
    }

    return normalPayAmount();
}

是不是逻辑更清晰明了了?

再看一个例子
if-else 语句一般在 for 循环里面使用,用于分支控制,如求 100 以内同时是 3、4、5 的倍数的题,如果我们根据题目所说的老老实实地判断符合倍数的情况,将会写成这样(假设每个 if 语句只判断一个条件):

for (int i = 1; i <= 100; i++) { 
   
	if (i%3 == 0){ 
   
	    if (i%4 == 0){ 
   
	        if (i%5 == 0){ 
   
	            System.out.println(i);
	        }
	    }
	}
}

这就是前面说的 “横放着的金字塔”,而如果我们逆向思考,从是 3、4、5 的倍数的反面思考,也就是哪些情况不是 3、4、5 的倍数,先把这些情况摘出来,然后结束本次循环,继续找下一个数。这样我们就能防止多层嵌套了:

for (int i = 1; i <= 100; i++) { 
   
	if (i%3 != 0){ 
   
	    continue;
	}
	if (i%4 != 0){ 
   
	    continue;
	}
	if (i%5 != 0){ 
   
	    continue;
	}
	System.out.println(i);
}

只有在上面三个条件都不成立的情况下,才会走到最后一步输出的语句。也就是排除那些不符合条件的情况,剩下的自然就是符合条件的了。希望通过这个小例子能让你明白到底什么是卫语句。

总结

函数中的条件逻辑使人难以看清正常的分支执行路径。使用卫语句表现所有特殊情况。

所谓卫语句,如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为“卫语句”。

一个直观的感受是,使用卫语句后能够让代码的逻辑更清晰且代码没那么臃肿。

但是这里仿佛又与另一个编程原则“单一出口原则”产生了冲突,实际在使用中这些所谓的原则应该灵活使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/126473.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ceres之LM算法「建议收藏」

    ceres之LM算法「建议收藏」Ceres作为一个优化算法库,在许多领域中有着至关重要的作用,比如slam系统中的优化问题-集束调整BA,就可以通过Ceres去实现,官方文档地址:http://ceres-solver.org/nnls_tutorial.html#bundle-adjustment本文主要是解析ceres中的LM算法过程,参考代码地址:https://github.com/ceres-solver/ceres-solver/tree/master/internal/ceres一、主要流程先贴个图,L.

    2022年10月1日
    2
  • 10000阶乘

    10000阶乘

    2022年1月12日
    51
  • c语言必备100代码(代码大全)

    一个完全入门初学者如何学代码,读代码和写代码,,我想学代码不知道方向谁能给我指明一个方向?1、学代码:前提是你的复有一个比较系统的学习.认真完成每一个课程中的案例.2、读代码:分制两步走:前期能读懂自己写的代码.2113后期能读懂他人写的代码和大致的知道底层的某些源码的含义.多去5261看开发文档(开发文档建议使用官方提供的4102英文版、不要使用中文自己害自己)3、写代码1653:前提是你要有…

    2022年4月18日
    1.2K
  • 【python】错误SyntaxError: invalid syntax的解决方法总结

    【python】错误SyntaxError: invalid syntax的解决方法总结今天学习了python,然而刚开始就出了一个难题,明明代码没有一点问题,可是每次运行都会显示“SyntaxError:invalidsyntax”。“SyntaxError:invalidsyntax”的意思就是语法错误;经过查询解决了这个问题,所以总结一个这个问题的解决方法:版本问题:因为python2和python3是不兼容的;可以尝试更换版本;粗心问题:忘…

    2022年5月28日
    170
  • 数据库设计工具MySQLWorkBench[通俗易懂]

    数据库设计工具MySQLWorkBench[通俗易懂]  该工具为MySQL官方提供地址:http://dev.mysql.com/downloads/workbench/小伙伴们注意按自己的操作系统选择下载版本。·       注意事项:安装后将环境语言配置成简体中文,否则中文乱码工作步骤新建模型后,会进入此页面。 1./2.切换数据库表设计与ER图。3. 创建/管理ER图4. 创建/管理表结构1….

    2022年7月11日
    20
  • 锁文件夹怎么锁_密码锁有没有开锁记录

    锁文件夹怎么锁_密码锁有没有开锁记录1.文件锁可以对将要修改文件的某个部分进行加锁,精确控制到字节通过fcntl()函数来进行设置文件锁fcntl(intfd,intcmd,………);参数:fd:文件描述符cmd

    2022年8月5日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号