前言

这是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...