关于go:Go常见错误系列第12篇冗余的嵌套代码

前言

这是Go常见谬误系列的第12篇:Go语言中冗余的嵌套代码,俗称箭头型代码。

素材来源于Go布道者,现Docker公司资深工程师Teiva Harsanyi。

本文波及的源代码全副开源在:Go常见谬误源代码,欢送大家关注公众号,及时获取本系列最新更新。

常见谬误

咱们先看看如下的代码:

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) {
    // ...
}

这段代码要做的事件很简略:

  • 把两个字符串s1和s2拼接起来,如果长度超过max,就只返回长度为max的子串。
  • 实现过程中,对s1和s2做了判空;对concatenate返回值有无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) {
    // ...
}

这段代码实现了和方才齐全一样的性能,然而可读性好很多。

那有什么最佳实际咱们能够作为参考,来标准代码实现呢?

最佳实际

通常来说,函数里的代码嵌套的档次越多,可读性就越差。能够参考如下准则来标准代码编写:

  • 当if语句里会return时,那不要持续用else了,间接把else里的内容和if放在同一个档次。

    bad case:

    if foo() {
        // ...
        return true
    } else {
        // ...
    }

    good case:

    if foo() {
        // ...
        return true
    }
    // ...
  • 如果批改判断条件,能够缩小嵌套档次,能够思考对判断条件做调整。示例如下:

    bad case:

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

    good case:

    if s == "" {
        return errors.New("empty string")
    }
    // ...
  • 演绎下面2个准则,其实就是能先return的就先return,缩小不必要的代码嵌套。

    感兴趣的也能够看看参考资料里”左耳朵耗子”写过的一篇文章”如何重构箭头型代码”,

下一篇文章,咱们会解说下Go语言里init函数的常见谬误和最佳实际。

举荐浏览

  • Go面试题系列,看看你会几题?
  • Go常见谬误第1篇:未知枚举值
  • Go常见谬误第2篇:benchmark性能测试的坑
  • Go常见谬误第3篇:go指针的性能问题和内存逃逸
  • Go常见谬误第4篇:break操作的注意事项
  • Go常见谬误第5篇:Go语言Error治理
  • Go常见谬误第6篇:slice初始化常犯的谬误
  • Go常见谬误第7篇:不应用-race选项做并发竞争检测
  • Go常见谬误第8篇:并发编程中Context应用常见谬误
  • Go常见谬误第9篇:应用文件名称作为函数输出
  • Go常见谬误第10篇:Goroutine和循环变量一起应用的坑
  • Go常见谬误第11篇:意外的变量遮蔽(variable shadowing

开源地址

文章和示例代码开源在GitHub: Go语言高级、中级和高级教程。

公众号:coding进阶。关注公众号能够获取最新Go面试题和技术栈。

集体网站:Jincheng’s Blog。

知乎:无忌。

福利

我为大家整顿了一份后端开发学习材料礼包,蕴含编程语言入门到进阶常识(Go、C++、Python)、后端开发技术栈、面试题等。

关注公众号「coding进阶」,发送音讯 backend 支付材料礼包,这份材料会不定期更新,退出我感觉有价值的材料。

发送音讯「进群」,和同行一起交流学习,答疑解惑。

References

  • https://livebook.manning.com/…
  • https://coolshell.cn/articles…

评论

发表回复

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

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理