Go语言必知必会100问题-02 减少代码的嵌套层数

news/2025/2/27 17:27:09/

减少代码的嵌套层数

软件开发中的“心智模型”用于描述开发人员在编码时心理活动,每段代码其实是人在编写这段代码时的心智模型投射,不能把代码看成是客观的存在,而是主观的产物,参合了当时心理活动或各种直觉感知。在编程时,必须不断维护心智模型,例如关于整体代码交互和功能实现的心智模型,代码是否具有可读性,代码风格,变量命名规范等。可读性强的代码需要的心智模型更简单,更容易阅读和维护。

代码嵌套层级的数量是影响可读性的一个关键因素,假设正在一个新项目上进行开发工作,并且需要读懂下面join函数实现的功能。此join函数实现的功能是将两个字符连接起来,如果连接起来的字符串超过给定的长度max,则返回前max个字符的子串。在处理的过程中,对参数进行检查并判断concatenate是否有返回错误。

func join(s1, s2 string, max int) (string, error) {if s1 == "" {return "", errors.New("s1 is empty")} else {if s2 == "" {return "", errors.New("s2 is empty")} else {concat, err := concatenate(s1, s2)if err != nil {return "", err} else {if len(concat) > max {return concat[:max], nil} else {return concat, nil}}}}
}func concatenate(s1 string, s2 string) (string, error) {// ...
}

从功能实现的角度来看,上述函数是正确的。然而,建立一个涵盖所有不同输入参数情况的心智模型可能不是一项简单的任务。为啥呢?由于代码嵌套的数量层级过多。现在,对上面的代码进行重构,得到新的实现如下。

func join(s1, s2 string, max int) (string, error) {if s1 == "" {return "", errors.New("s1 is empty")}if s2 == "" {return "", errors.New("s2 is empty")}concat, err := concatenate(s1, s2)if err != nil {return "", err}if len(concat) > max {return concat[:max], nil}return concat, nil
}func concatenate(s1 string, s2 string) (string, error) {// ...
}

对比这两种实现,虽然功能一样,但是阅读这个新版本的心智模型需要的认知负荷更少,因为新版实现中函数嵌套层级更少。正如Mat Ryer(Go Time播客小组成员)所说:

将正常情况逻辑(happy path)向左对齐,阅读时能够快速向下扫描一列可以查看预期的执行流程。

由于存在嵌套的if/else语句,很难看出重构前版本中的预期执行流程。相反,重构后的版本眼睛只需向下扫描一列便可知道预期的执行流程,通过第二列了解各种特殊情况的处理逻辑。

在这里插入图片描述

一般来说,函数需要的嵌套层数越多,阅读和理解就越复杂。下面来看看如何使用这条规则优化代码的可读性。

  • 当if语句在满足和不满足都有逻辑处理时,我们应该省略else语句块,不应该像下面这样写.
if foo() {// ...return true
} else {// ...
}

而应该像下面这样写,将else语句省略掉,并将else语句块中的逻辑移动到顶层,使其更易于阅读。

if foo() {return true
}
// ...
  • 对于像下面这种if语句是一条non-happy路径,可以通过改变比较条件来减少代码块数量。
if s != "" {// ...
} else {return errors.New("empty string")
}

上面s为空是一个non-happy路径,我们可以通过翻转条件,得到如下实现。下面这种实现就更容易阅读,因为它将快乐路径放在了左边并减少了代码块的数量。

if s == "" {return errors.New("empty string")
}
// ...

编写可读的代码对每个开发人员来说都是一项重要的挑战,努力减少代码块嵌套的层级数量,将快乐路径对齐放在左侧,并尽早返回是提高代码可读性的具体手段,在工作中,我们应该应用这些手段。


http://www.ppmy.cn/news/33369.html

相关文章

特征建模之FiBiNet

FiBiNet: Combine Feature importance and Bilinear feature Interaction for Click-Through Rate Prediction https://arxiv.org/abs/1905.0943 一、特征建模的重要性 推荐领域的深度CTR模型中的参数主要由两部分构成:特征Embedding参数和MLP层参数,假…

【基于协同过滤算法的推荐系统项目实战-2】了解协同过滤推荐系统

本文目录1、推荐系统的关键元素1.1 数据1.2 算法1.3 业务领域1.4 展示信息2、推荐算法的主要分类2.1 基于关联规则的推荐算法基于Apriori的算法基于FP-Growth的算法2.2 基于内容的推荐算法2.3 基于协同过滤的推荐算法3、推荐系统常见的问题1、冷启动2、数据稀疏3、不断变化的用…

Spark SQL函数定义【博学谷学习记录】

1 如何使用窗口函数窗口函数格式:分析函数 over(partition by xxx order by xxx [asc|desc] [rows between xxx and xxx])学习的相关分析函数有那些? 第一类: row_number() rank() dense_rank() ntile()第二类: 和聚合函数组合使用 sum() avg() max() min() count()第三类: la…

博客系统实现自动化测试

目录 一、设计博客系统的测试用例 二、利用测试用例进行测试 测试登录页面 界面测试 功能测试 测试博客列表页 界面测试 功能测试 测试博客详情页 界面测试 功能测试 博客编辑页测试 界面测试 功能测试 一、设计博客系统的测试用例 二、利用测试用例进行测…

微信小程序项目实例——扫雷

今日推荐💁‍♂️ 2023许嵩演唱会即将到来🎤🎤🎤大家一起冲冲冲🏃‍♂️🏃‍♂️🏃‍♂️ 🔮🔮🔮🔮🔮往期优质项目实例&#x1f52e…

【JavaEE初阶】第八节.网络原理网络层和数据链路层,应用层

文章目录 前言 一、网络层协议 1.1 IP协议 1.2 IP地址; 1.3 路由选择; 二、数据链路层 2.1 以太网协议; 三、应用层; 3.1 应用层协议DNS; 3.2 DNS是如何完成转换的; 3.3 如何解决DNS访问量太高的…

学习28个案例总结

学习前 对于之前遇到的问题没有及时总结,导致做什么事情都是新的一样。没有把之前学习到接触到的内容应用上。通过这次对28个案例的学习。把之前遇到的问题总结成自己的经验,在以后的开发过程中避免踩重复性的坑。多看帮助少走弯路。 学习中 对28个案例…

C/C++每日一练(20230319)

目录 1. 反转链表 II 🌟🌟 2. 解码方法 🌟🌟 3. 擅长编码的小k 🌟🌟🌟 🌟 每日一练刷题专栏 🌟 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 …