编程中的卫语句

什么是卫语句在《阿里巴巴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)
上一篇 2022年4月7日 下午9:00
下一篇 2022年4月7日 下午9:00


相关推荐

  • Notion添加按钮教程与自动化设置详解

    Notion添加按钮教程与自动化设置详解

    2026年3月19日
    2
  • 单调栈应用[通俗易懂]

    单调栈应用[通俗易懂]题意大概让算t秒每一秒的最短路和,每条边每秒dis++;dp算距离dis[i][j]:1到i点走j条边的最短路O(n(n+m));单调栈维护个上凸;等差数列n^2求解;代码:#include#include#include#include#includeusingnamespacest

    2026年2月14日
    3
  • Selenium + Pycharm 搭建自动化测试环境

    Selenium + Pycharm 搭建自动化测试环境今天尝试搭建了 Selenuim Pycharm 的自动化测试环境 过程如下 1 安装 Python 用的 3 5 安装的过程中记得选中将 Python 目录设置到 Path 中 免得后继手动添加 2 安装 Selenium 因为安装的 Python3 5 已经自带了 pip 所以我们只需要进入 cmd 进入 Python 安装目录下的 Scripts 文件夹 直接输入命令 pipinstall

    2026年3月27日
    1
  • 高通8953平台usb转以太网芯片ax88772驱动

    高通8953平台usb转以太网芯片ax88772驱动高通 8953 平台 usb 转以太网芯片 ax88772 驱动文章目录高通 8953 平台 usb 转以太网芯片 ax88772 驱动 ax88772 电路图 ax88772mac 地址烧录工具使用说明增加 eeprom 的读写 USB 读写函数进入 eeprom 获取数据读写 eeprom 检查网络设备的 mac 地址获取 mac 地址可能遇到的问题分析 ax8872 针对 eeprom 无法写入信息排查关于 eeprom 器件的焊接关于 eeprom 器件的选择问题烧录工具无法使用内核版本 Linux4 4 平台 rk3399 amp 高通 8953

    2026年3月26日
    2
  • windows上开启winrm服务

    windows上开启winrm服务最近配置 ansible 管理 Windows 机器 需要启用 winrm 的服务 所以要在 windows 平台上启用 winrm 服务 winrmservice 默认都是未启用的状态 先查看状态 如无返回信息 则是没有启动 打开 powershell 终端 输入下列命令进行配置 winrmenumera config listener 针对 winrmservice 进行基础配置

    2026年3月20日
    2
  • 管程 java_Synchronized之管程

    管程 java_Synchronized之管程Java 对象如何与 Monitor 关联如图所示 依次对图中进行解释 java 对象与 monitor 的关联图我们知道 JVM 堆中存放的是对象实例 对象实例包括几个部分 分别是与对象实例无关的对象头 实例数据 填充数据 对象头中包括几个部分 MarkWord 和指向元数据的指针 所占内存为 2 JVM 位数 在 32bitJVM 中就占 8 个字节 MarkWord 和指向元数据的指针分别占一个 JVM 位数 注意 如果

    2026年3月18日
    1

发表回复

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

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