前言
这是 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…