Skip to content

Commit

Permalink
update fundamentals to 1.22
Browse files Browse the repository at this point in the history
  • Loading branch information
zigo101 committed Mar 17, 2024
1 parent 8a4f996 commit 74a52b2
Show file tree
Hide file tree
Showing 26 changed files with 222 additions and 110 deletions.
2 changes: 1 addition & 1 deletion pages/fundamentals/101.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</p>

<p>
The book is Go 1.21 ready now (<a href="100-updates.html">update history</a>).
The book is Go 1.22 ready now (<a href="100-updates.html">update history</a>).
</p>

<p><small><i>
Expand Down
2 changes: 2 additions & 0 deletions pages/fundamentals/acknowledgements.html
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ <h1>Acknowledgments</h1>
ursatong,
Eric (kuchaguangjie),
Cheng (mazeyqian),
DrejT,
Wildan S. Nahar,
etc.
</p>

Expand Down
2 changes: 1 addition & 1 deletion pages/fundamentals/bounds-check-elimination.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ <h3>Example 1</h3>
</p>

<p>
Please note that, up to now (Go Toolchain 1.21.n), the standard compiler
Please note that, up to now (Go Toolchain 1.22.n), the standard compiler
doesn't check BCE for an operation in a generic function if the operation
involves type parameters and the generic function is never instantiated.
</p>
Expand Down
2 changes: 1 addition & 1 deletion pages/fundamentals/concurrent-atomic-operation.html
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ <h3>Atomic Operations for Integers</h3>
</p>

<p>
Please note, up to now (Go 1.21), atomic operations for 64-bit words,
Please note, up to now (Go 1.22), atomic operations for 64-bit words,
a.k.a. int64 and uint64 values,
require the 64-bit words must be 8-byte aligned in memory.
For Go 1.19 introduced atomic method operations, this requirement is always satisfied,
Expand Down
4 changes: 2 additions & 2 deletions pages/fundamentals/concurrent-common-mistakes.html
Original file line number Diff line number Diff line change
Expand Up @@ -168,15 +168,15 @@ <h3>Use <code>time.Sleep</code> Calls to Do Synchronizations</h3>
<p>
What do you expect the program will output? <code>123</code>, or <code>789</code>?
In fact, the output is compiler dependent.
For the standard Go compiler 1.21.n,
For the standard Go compiler 1.22.n,
it is very possible the program will output <code>123</code>.
But in theory, it might also output <code>789</code>.
</p>

<p>
Now, let's change <code>c &lt;- n + 0</code> to <code>c &lt;- n</code>
and run the program again, you will find the output becomes to <code>789</code>
(for the standard Go compiler 1.21.n).
(for the standard Go compiler 1.22.n).
Again, the output is compiler dependent.
</p>

Expand Down
55 changes: 27 additions & 28 deletions pages/fundamentals/container.html
Original file line number Diff line number Diff line change
Expand Up @@ -1044,7 +1044,7 @@ <h3>Append and Delete Container Elements</h3>

<p>
The first argument of an <code>append</code> function
call can't be an untyped <code>nil</code> (up to Go 1.21).
call can't be an untyped <code>nil</code> (up to Go 1.22).
</p>

</div>
Expand Down Expand Up @@ -1634,7 +1634,7 @@ <h3>Copy Slice Elements With the Built-in <code>copy</code> Function</h3>

<p>
Neither of the two arguments of a <code>copy</code>
function call can be an untyped <code>nil</code> value (up to Go 1.21).
function call can be an untyped <code>nil</code> value (up to Go 1.22).
</p>

</div>
Expand Down Expand Up @@ -1962,15 +1962,15 @@ <h3>Container Element Iterations</h3>
<p>
</p>

Before Go 1.22, for a <code>for-range</code> loop block
Prior to Go 1.22, when a <code>for-range</code> loop block
(note the sign before before <code>range</code> is <code>:=</code>)

<pre class="line-numbers"><code class="language-go">for key, element := range aContainer {...}
</code></pre>

all key-element pairs will be assigned to <b>the same</b> iteration variable pair.
However, since Go 1.22, each key-element pair will be assigned to a <b>distinctive</b> iteration variable pair
(a.k.a. a distinctive instance will be created for each iteration variable in each loop step).
is executed, all key-element pairs will be assigned to <b>the same</b> iteration variable instance pair.
However, since Go 1.22, each key-element pair will be assigned to a <b>distinctive</b> iteration variable instance pair
(a.k.a. a distinctive instance will be created for each iteration variable in each loop iteration).

<p></p>

Expand All @@ -1990,22 +1990,21 @@ <h3>Container Element Iterations</h3>
}
</code></pre>

Use different versions of Go Toolchain to run the code
Use different Go Toolchain versions to run the code
(<a href="https://go101.org/apps-and-libs/gotv.html">gotv</a> is a tool used to
manage and use multiple coexisting installations of official Go toolchain versions;
the coming Go 1.22 versions will be based on the current tip version),
manage and use multiple coexisting installations of official Go toolchain versions),
we will get different outputs:

<pre class="line-numbers"><code class="language-go">$ gotv 1.21. run forrange1.go
[Run]: $HOME/.cache/gotv/tag_go1.21.2/bin/go run forrange1.go
2 3
2 3
2 3
$ gotv :tip run forrange1.go
[Run]: $HOME/.cache/gotv/bra_master/bin/go run forrange1.go
2 3
1 2
0 1
[Run]: $HOME/.cache/gotv/tag_go1.21.8/bin/go run forrange1.go
2 2
2 2
2 2
$ gotv 1.22. run forrange1.go
[Run]: $HOME/.cache/gotv/tag_go1.22.1/bin/go run forrange1.go
2 2
1 1
0 0
</code></pre>

<p></p>
Expand All @@ -2030,18 +2029,18 @@ <h3>Container Element Iterations</h3>
Use different Go Toolchain versions, we will get the following outputs:

<pre class="line-numbers"><code class="language-go">$ gotv 1.21. run forrange2.go
[Run]: $HOME/.cache/gotv/tag_go1.21.2/bin/go run forrange2.go
[Run]: $HOME/.cache/gotv/tag_go1.21.8/bin/go run forrange2.go
2
$ gotv :tip run forrange2.go
[Run]: $HOME/.cache/gotv/bra_master/bin/go run forrange2.go
$ gotv 1.22. run forrange2.go
[Run]: $HOME/.cache/gotv/tag_go1.22.1/bin/go run forrange2.go
6
</code></pre>

<p>
Therefore, this is a semantic change that breaks backward compatibility.
But the new semantic is actually more in line with people's expectations;
and in theory, no old logic-correct code has been found will
be broken by this change.
Therefore, this is a semantic change which breaks backward compatibility.
But the new semantic is actually more in line with people's expectations.
And in theory, no old code that was found to be logically correct
would be broken by this change.
</p>

</div>
Expand Down Expand Up @@ -2342,7 +2341,7 @@ <h3>More Slice Manipulations</h3>
<h4>Clone slices</h4>

<div>
For the current Go version (1.21), the simplest way to clone a slice is:
For the current Go version (1.22), the simplest way to clone a slice is:
<pre class="disable-line-numbers111"><code class="language-go">sClone := append(s[:0:0], s...)
</code></pre>

Expand All @@ -2359,7 +2358,7 @@ <h4>Clone slices</h4>
copy(sClone, s)

// Or the following one-line make+append way.
// As of Go Toolchain v1.21.n, this way is a bit
// As of Go Toolchain v1.22.n, this way is a bit
// slower than the above two-line make+copy way.
sClone := append(make([]T, 0, len(s)), s...)
</code></pre>
Expand Down Expand Up @@ -2559,7 +2558,7 @@ <h4>Insert all elements of a slice into another slice</h4>
// might make at most two allocations.
// The following verbose way always copies s[i:]
// once and will only make at most one allocation.
// However, as of Go Toolchain v1.21.n, the "make"
// However, as of Go Toolchain v1.22.n, the "make"
// call will clear partial of just allocated elements,
// which is actually unnecessary. So the verbose
// way is more efficient than the one-line way
Expand Down
46 changes: 32 additions & 14 deletions pages/fundamentals/control-flows-more.html
Original file line number Diff line number Diff line change
Expand Up @@ -375,8 +375,8 @@ <h3>Goroutine Schedule</h3>
<p>
At runtime. we can call the <a href="https://golang.org/pkg/runtime/#GOMAXPROCS"><code>runtime.GOMAXPROCS</code></a>
function to get and set the number of logical processors (<b>P</b>s).
For the standard Go runtime, before Go 1.5, the default initial value of this number is <code>1</code>,
but since Go 1.5, the default initial value of this number is equal to
For the standard Go runtime, before Go Toolchain 1.5, the default initial value of this number is <code>1</code>,
but since Go Toolchain 1.5, the default initial value of this number is equal to
the number of logical CPUs available for the current running program.
The default initial value (the number of logical CPUs) is the best choice for most programs.
But for some file IO heavy programs, a <code>GOMAXPROCS</code> value larger than <code>runtime.NumCPU()</code> may be helpful.
Expand Down Expand Up @@ -515,44 +515,61 @@ <h3>The Evaluation Moment of the Arguments of Deferred Function Calls</h3>
</p>

Here is an example.
<pre class="line-numbers"><code class="language-go">package main
<pre class="line-numbers"><code class="language-go">// eval-moment.go
package main

import "fmt"

func main() {
func() {
var x = 0
for i := 0; i < 3; i++ {
defer fmt.Println("a:", i)
defer fmt.Println("a:", i + x)
}
x = 10
}()
fmt.Println()
func() {
var x = 0
for i := 0; i < 3; i++ {
defer func() {
fmt.Println("b:", i)
fmt.Println("b:", i + x)
}()
}
x = 10
}()
}
</code></pre>

Run it. The output:
<pre class="output"><code>a: 2
Use different Go Toolchain versions to run the code
(<a href="https://go101.org/apps-and-libs/gotv.html">gotv</a> is a tool used to
manage and use multiple coexisting installations of official Go toolchain versions).
The outputs:
<pre class="output"><code>$ gotv 1.21. run eval-moment.go
[Run]: $HOME/.cache/gotv/tag_go1.21.8/bin/go run eval-moment.go
a: 2
a: 1
a: 0

b: 13
b: 13
b: 13
$ gotv 1.22. run eval-moment.go
[Run]: $HOME/.cache/gotv/tag_go1.22.1/bin/go run eval-moment.go
a: 2
a: 1
a: 0

b: 3
b: 3
b: 3
b: 12
b: 11
b: 10
</code></pre>

<p>
The first loop prints <code>i</code> as <code>2</code>, <code>1</code> and <code>0</code> as a sequence.
The second loop always prints <code>i</code> as <code>3</code>,
because when the three <code>fmt.Println</code> calls within the anonymous function are invoked,
the value of the loop variable <code>i</code> has changed to <code>3</code>.
Please note the behavior change caused by <a href="control-flows.html#for-semantic-change">the semantic change (of <code>for</code> loop blocks) made in Go 1.22</a>.
</p>

<!--
To make the second loop print the same result as the first one,
we can modify the second loop as
Expand All @@ -577,6 +594,7 @@ <h3>The Evaluation Moment of the Arguments of Deferred Function Calls</h3>
<p>
</p>
-->

The same argument valuation moment rules also apply to goroutine function calls.
The following program will output <code>123 789</code>.
Expand Down
Loading

0 comments on commit 74a52b2

Please sign in to comment.