diff --git a/README.md b/README.md index 3a3eee1..3824c01 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Go tips from [Phuong Le](https://twitter.com/func25). | 19 | | | | 20 | Pass values, not pointers | smallnest | | 21 | | | -| 22 | | | +| 22 | Simplify function signatures with structs or variadic options | zhubiaook | | 23 | Skip the 'Get' prefix for getters | HBUzxl | | 24 | | | | 25 | Prefer 'chan struct{}' over 'chan bool' for signaling between goroutines | justlorain | @@ -84,7 +84,7 @@ Go tips from [Phuong Le](https://twitter.com/func25). | 28 | Converting multiple if-else statements into switch cases | zzzpppy | | 29 | Avoid context.Background(), make your goroutines promisable. | stonemax | | 30 | 使用context.WithoutCancel()继续上下文操作 | smallnest | -| 31 | | | +| 31 | Loop labels for cleaner breaks and continues | zhubiaook | | 32 | | | | 33 | | | | 34 | | | diff --git a/src/031.md b/src/031.md new file mode 100644 index 0000000..b8c473e --- /dev/null +++ b/src/031.md @@ -0,0 +1,44 @@ +# Tip #31 使用跳转标签让break和continue语句更简洁 + +> 原始链接:[Golang Tip #31: Loop labels for cleaner breaks and continues](https://twitter.com/func25/status/1761694371240702098) +> + +通常避免使用标签和`goto` 语句,因为会降低代码可读性,使其难以理解。 + +![](./images/031/031_01.png) + +上面简短的示例看起来很清晰易懂。但是随着代码复杂度的增加,可读性会大大降低: + +* 你可能要在距离`goto` 语句“数百英里”之外才能找到目的标签。 + +* 你需要在代码上下文中去寻找`goto`语句跳转的目的标签在哪里。 + +### 跳转标签 + +例如,在处理嵌套循环时,某些情况下使用跳转标签是很不错的实践。 + +想象一下,我们在二维数组中搜索一个数字: + +![](./images/031/031_02.png) + +此时,你有一个更优雅的解决方案:在循环语句处声明跳转标签。 + +一旦声明了标签以后,你就可以使用`break` 或 `continue` 后跟一个标签实现不仅本层循环的跳转,任何外层循环的跳转都可以。 + +这样做的结果是? + +代码不仅简短,而且更加清晰、明了。 + +![](./images/031/031_03.png) + +我们可以在`break` 和 `continue` 语句中都使用标签。 + +另外一个有用的实例是当循环代码块中包含`select{}`。 + +如果你在`select` 代码块中使用了不带标签的`break`,只会跳出`select`代码块,而不会跳出包含它的外层循环。 + +![](./images/031/031_04.png) + +本节的技巧主要针对循环,但也可以使用在其他地方,比如`switch`实例: + +![](./images/031/031_05.png) diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e34ea0b..0493aeb 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -24,6 +24,7 @@ - [Tip #28 将多个if-else语句转换为switch](./028.md) - [Tip #29 避免使用 context.Background,使你的协程具备承诺性](./029.md) - [Tip #30 使用context.WithoutCancel()继续上下文操作](./030.md) +- [Tip #31 使用跳转标签让break和continue语句更简洁](./031.md) - [Tip #38 使用 fmt.Errorf 使你的错误信息清晰明了,不要让它们过于赤裸](./038.md) - [Tip #40 在使用defer时处理错误以防止静默失败](./040.md) - [Tip #43 优雅关闭你的应用程序](./043.md) diff --git a/src/images/.DS_Store b/src/images/.DS_Store deleted file mode 100644 index c34b738..0000000 Binary files a/src/images/.DS_Store and /dev/null differ diff --git a/src/images/031/031_01.png b/src/images/031/031_01.png new file mode 100644 index 0000000..06084db Binary files /dev/null and b/src/images/031/031_01.png differ diff --git a/src/images/031/031_02.png b/src/images/031/031_02.png new file mode 100644 index 0000000..2cf65f8 Binary files /dev/null and b/src/images/031/031_02.png differ diff --git a/src/images/031/031_03.png b/src/images/031/031_03.png new file mode 100644 index 0000000..21d617c Binary files /dev/null and b/src/images/031/031_03.png differ diff --git a/src/images/031/031_04.png b/src/images/031/031_04.png new file mode 100644 index 0000000..46e8fb2 Binary files /dev/null and b/src/images/031/031_04.png differ diff --git a/src/images/031/031_05.png b/src/images/031/031_05.png new file mode 100644 index 0000000..e27be0c Binary files /dev/null and b/src/images/031/031_05.png differ