diff --git a/docs/index.md b/docs/index.md index e6b8c95..bd6d6c6 100644 --- a/docs/index.md +++ b/docs/index.md @@ -535,7 +535,7 @@ It’s essential to understand how to use `==` and `!=` to make comparisons effe * _Channels_—Compare whether two channels were created by the same call to make or if both are nil. * _Interfaces_—Compare whether two interfaces have identical dynamic types and equal dynamic values or if both are nil. * _Pointers_—Compare whether two pointers point to the same value in memory or if both are nil. -* _Structs and arrays)—Compare whether they are composed of similar types. +* _Structs and arrays_—Compare whether they are composed of similar types. ???+ note @@ -645,7 +645,7 @@ One essential rule to keep in mind is that a `break` statement terminates the ex To break the loop instead of the `switch` statement, the most idiomatic way is to use a label: -```go +```go hl_lines="1 8" loop: for i := 0; i < 5; i++ { fmt.Printf("%d ", i) @@ -790,7 +790,7 @@ for i, r := range s { Or, we can convert the string into a slice of runes and iterate over it: -```go +```go hl_lines="2" s := "hêllo" runes := []rune(s) for i, r := range runes { @@ -854,7 +854,7 @@ During each iteration, the `+=` operator concatenates `s` with the value string. Fortunately, there is a solution to deal with this problem, using `strings.Builder`: -```go +```go hl_lines="2 4" func concat(values []string) string { sb := strings.Builder{} for _, value := range values { @@ -944,7 +944,7 @@ A receiver _must_ be a pointer type slice []int func (s *slice) add(element int) { - *s = append(*s, element) + *s = append(*s, element) } ``` @@ -1085,25 +1085,13 @@ Two leading options if we want to keep using `defer`. The first solution is to pass a string pointer: -```go +```go hl_lines="3 4" func f() error { var status string defer notify(&status) defer incrementCounter(&status) // The rest of the function unchanged - if err := foo(); err != nil { - status = StatusErrorFoo - return err - } - - if err := bar(); err != nil { - status = StatusErrorBar - return err - } - - status = StatusSuccess - return nil } ``` @@ -1111,7 +1099,7 @@ Using `defer` evaluates the arguments right away: here, the address of status. Y There’s another solution: calling a closure (an anonymous function value that references variables from outside its body) as a `defer` statement: -```go +```go hl_lines="3 4 5 6" func f() error { var status string defer func() { @@ -1628,7 +1616,7 @@ ch <- 0 Then what’s the purpose of Go allowing messages to be received from or sent to a nil channel? For example, we can use nil channels to implement an idiomatic way to merge two channels: -```go +```go hl_lines="5 9 15" func merge(ch1, ch2 <-chan int) <-chan int { ch := make(chan int, 1) diff --git a/mkdocs.yml b/mkdocs.yml index d231d93..749837a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -80,6 +80,7 @@ markdown_extensions: anchor_linenums: true line_spans: __span pygments_lang_class: true + - pymdownx.highlight - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences diff --git a/site/index.html b/site/index.html index 972e284..f9d6d00 100644 --- a/site/index.html +++ b/site/index.html @@ -3123,7 +3123,7 @@ Meanwhile, we should also look at golangci-lint ( Note @@ -3207,15 +3207,15 @@ One additional note: we must remember that the standard library has some existin

The break statement doesn’t terminate the for loop: it terminates the switch statement, instead. Hence, instead of iterating from 0 to 2, this code iterates from 0 to 4: 0 1 2 3 4.

One essential rule to keep in mind is that a break statement terminates the execution of the innermost for, switch, or select statement. In the previous example, it terminates the switch statement.

To break the loop instead of the switch statement, the most idiomatic way is to use a label:

-
loop:
-    for i := 0; i < 5; i++ {
+
loop:
+    for i := 0; i < 5; i++ {
         fmt.Printf("%d ", i)
 
         switch i {
         default:
         case 2:
-            break loop
-        }
+            break loop
+        }
     }
 

Here, we associate the loop label with the for loop. Then, because we provide the loop label to the break statement, it breaks the loop, not the switch. Therefore, this new version will print 0 1 2, as we expected.

@@ -3320,8 +3320,8 @@ One additional note: we must remember that the standard library has some existin

Or, we can convert the string into a slice of runes and iterate over it:

s := "hêllo"
-runes := []rune(s)
-for i, r := range runes {
+runes := []rune(s)
+for i, r := range runes {
     fmt.Printf("position %d: %c\n", i, r)
 }
 
@@ -3362,10 +3362,10 @@ One additional note: we must remember that the standard library has some existin

During each iteration, the += operator concatenates s with the value string. At first sight, this function may not look wrong. But with this implementation, we forget one of the core characteristics of a string: its immutability. Therefore, each iteration doesn’t update s; it reallocates a new string in memory, which significantly impacts the performance of this function.

Fortunately, there is a solution to deal with this problem, using strings.Builder:

func concat(values []string) string {
-    sb := strings.Builder{}
-    for _, value := range values {
-        _, _ = sb.WriteString(value)
-    }
+    sb := strings.Builder{}
+    for _, value := range values {
+        _, _ = sb.WriteString(value)
+    }
     return sb.String()
 }
 
@@ -3427,7 +3427,7 @@ One additional note: we must remember that the standard library has some existin
type slice []int
 
 func (s *slice) add(element int) {
-          *s = append(*s, element)
+    *s = append(*s, element)
 }