-
-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Video: https://youtu.be/EL4hg73mT2A * Blog Post: https://mariocarrion.com/2024/10/02/what-is-new-in-go-1-23.html
- Loading branch information
1 parent
25bea82
commit b2afde2
Showing
16 changed files
with
420 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
go123/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Range over func | ||
|
||
Excerpt from official release notes: | ||
|
||
> The "range" clause in a "for-range" loop now accepts iterator functions of the following types | ||
> | ||
> func(func() bool) | ||
> func(func(K) bool) | ||
> func(func(K, V) bool) | ||
> | ||
> as range expressions. | ||
[Go Wiki: Rangefunc Experiment](https://go.dev/wiki/RangefuncExperiment) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"time" | ||
) | ||
|
||
// func(func() bool) | ||
func Iter1() func(func() bool) { | ||
return func(yield func() bool) { | ||
var i int | ||
|
||
for { | ||
if !yield() { | ||
return | ||
} | ||
i++ | ||
|
||
fmt.Println(i, time.Now()) | ||
} | ||
} | ||
} | ||
|
||
// func(func(K) bool) | ||
func Iter2() func(func(int) bool) { | ||
return func(yield func(int) bool) { | ||
var v int | ||
|
||
for { | ||
if !yield(v) { | ||
return | ||
} | ||
v += 10 | ||
} | ||
} | ||
} | ||
|
||
// func(func(K, V) bool) | ||
func Iter3() func(func(int, int) bool) { | ||
return func(yield func(int, int) bool) { | ||
var v int | ||
|
||
for { | ||
if !yield(v, v+10) { | ||
return | ||
} | ||
v++ | ||
} | ||
} | ||
} | ||
|
||
func MultiplyBy2(vals ...int) []int { | ||
res := make([]int, len(vals)) | ||
for i, v := range vals { | ||
res[i] = v * 2 | ||
} | ||
return res | ||
} | ||
|
||
func MultiplyBy2Iter(vals ...int) func(func(int, int) bool) { | ||
return func(yield func(int, int) bool) { | ||
for i, v := range vals { | ||
if !yield(i, v*2) { | ||
return | ||
} | ||
} | ||
} | ||
} | ||
|
||
func main() { | ||
var i = 0 | ||
for range Iter1() { // can't "for _ = range Basic()" | ||
if i == 5 { | ||
break | ||
} | ||
i++ | ||
time.Sleep(10 * time.Millisecond) | ||
} | ||
|
||
fmt.Println("---") | ||
|
||
for v := range Iter2() { | ||
if v == 50 { | ||
break | ||
} | ||
|
||
fmt.Println(v, time.Now()) | ||
} | ||
|
||
fmt.Println("---") | ||
|
||
for i, v := range Iter3() { | ||
if i == 5 { | ||
break | ||
} | ||
|
||
fmt.Println(i, v, time.Now()) | ||
} | ||
|
||
//- | ||
|
||
fmt.Println("---") | ||
|
||
for i, v := range MultiplyBy2(1, 2, 3, 4, 5, 6) { | ||
fmt.Println(i, v) | ||
} | ||
|
||
fmt.Println("---") | ||
|
||
for i, v := range MultiplyBy2Iter(1, 2, 3, 4, 5, 6) { | ||
fmt.Println(i, v) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# `unique` package | ||
|
||
Excerpt from official release notes: | ||
|
||
> The new unique package provides facilities for canonicalizing values (like | ||
> “interning” or “hash-consing”). | ||
> | ||
> Any value of comparable type may be canonicalized with the new Make[T] | ||
> function, which produces a reference to a canonical copy of the value in the | ||
> form of a Handle[T]. Two Handle[T] are equal if and only if the values used | ||
> to produce the handles are equal, allowing programs to deduplicate values and | ||
> reduce their memory footprint. Comparing two Handle[T] values is efficient, | ||
> reducing down to a simple pointer comparison. | ||
[pkg.go.dev/unique](https://pkg.go.dev/unique) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"unique" | ||
) | ||
|
||
// `comparable` | ||
type User struct { | ||
Name string | ||
LastName string | ||
} | ||
|
||
// Not `comparable` | ||
type Group struct { | ||
Name string | ||
Users []User | ||
} | ||
|
||
func main() { | ||
h1 := unique.Make(User{Name: "Mario", LastName: "Carrion"}) | ||
h2 := unique.Make(User{Name: "Mario", LastName: "Carrion"}) | ||
|
||
fmt.Println("same values?", h1 == h2) | ||
fmt.Printf("addresses: %v - %v\n", h1, h2) | ||
|
||
// Group does not satisfy comparable | ||
// g1 := unique.Make(Group{Name: "Mario",Users: []User{}}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# `iter` package | ||
|
||
Excerpt from official release notes: | ||
|
||
> Package iter provides basic definitions and operations related to iterators | ||
> over sequences. | ||
[pkg.go.dev/iter](https://pkg.go.dev/iter) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"iter" | ||
"time" | ||
) | ||
|
||
// iter.Seq[V any] func(yield func(V) bool) -- One value | ||
// iter.Seq2[K, V any] func(yield func(K, V) bool) -- Two values: typically key-value or index-value pairs | ||
|
||
// func(func(K, V) bool) | ||
func Iter() func(func(int, int) bool) { | ||
return func(yield func(int, int) bool) { | ||
var v int | ||
|
||
for { | ||
if !yield(v, v+10) { | ||
return | ||
} | ||
v++ | ||
} | ||
} | ||
} | ||
|
||
func main() { | ||
for i, v := range Iter() { | ||
if i == 5 { | ||
break | ||
} | ||
|
||
fmt.Println(i, v, time.Now()) | ||
} | ||
|
||
//- | ||
|
||
next, stop := iter.Pull2(Iter()) | ||
defer stop() | ||
|
||
for { | ||
i, v, ok := next() | ||
if !ok { | ||
break | ||
} | ||
|
||
if i == 5 { | ||
break | ||
} | ||
|
||
fmt.Println(i, v, time.Now()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# `slices` package changes | ||
|
||
The `slices` package adds **9 functions** that support iterators: | ||
|
||
* [All](https://go.dev/pkg/slices#All) returns an iterator over slice indexes and values. | ||
* [AppendSeq](https://go.dev/pkg/slices#AppendSeq) appends values from an iterator to an existing slice. | ||
* [Backward](https://go.dev/pkg/slices#Backward) returns an iterator that loops over a slice backward. | ||
* [Chunk](https://go.dev/pkg/slices#Chunk) returns an iterator over consecutive sub-slices of up to n elements of a slice. | ||
* [Collect](https://go.dev/pkg/slices#Collect) collects values from an iterator into a new slice. | ||
* [Sorted](https://pkg.go.dev/slices#Sorted) Sorted collects values from seq into a new slice, sorts the slice, and returns it. | ||
* [SortedFunc](https://go.dev/pkg/slices#SortedFunc) is like Sorted but with a comparison function. | ||
* [SortedStableFunc](https://go.dev/pkg/slices#SortedStableFunc) is like SortFunc but uses a stable sort algorithm. | ||
* [Sorted](https://go.dev/pkg/slices#Sorted) collects values from an iterator into a new slice, and then sorts the slice. | ||
* [Values](https://go.dev/pkg/slices#Values) returns an iterator over slice elements. | ||
|
||
[pkg.go.dev/slices](https://pkg.go.dev/slices) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"slices" | ||
) | ||
|
||
func main() { | ||
numbers := []string{"5", "4", "3", "2", "1"} | ||
fmt.Printf("numbers = %v\n", numbers) | ||
|
||
// slices.Chunk | ||
fmt.Printf("\nslices.Chunk(numbers, 2)\n") | ||
for c := range slices.Chunk(numbers, 2) { | ||
fmt.Printf("\t%s\n", c) | ||
} | ||
|
||
// slices.Collect | ||
fmt.Printf("\nslices.Collect(slices.Chunk(numbers, 2))\n") | ||
numbers1 := slices.Collect(slices.Chunk(numbers, 2)) | ||
fmt.Printf("\t%s\n", numbers1) | ||
|
||
// slices.Sorted + slices.Values | ||
fmt.Printf("\nslices.Sorted(slices.Values(numbers))\n") | ||
sorted := slices.Sorted(slices.Values(numbers)) | ||
fmt.Printf("\t%v\n", sorted) | ||
|
||
fmt.Printf("\nslices.Backward(numbers)\n") | ||
for i, v := range slices.Backward(numbers) { | ||
fmt.Printf("\ti: %d, v: %s\n", i, v) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# `maps` package changes | ||
|
||
The `maps` package adds **5 functions** that support iterators: | ||
|
||
* [All](https://pkg.go.dev/maps#All) returns an iterator over key-value pairs from a map. | ||
* [Collect](https://pkg.go.dev/maps#Collect) collects key-value pairs from an iterator into a new map and returns it. | ||
* [Insert](https://pkg.go.dev/maps#Insert) adds the key-value pairs from an iterator to an existing map. | ||
* [Keys](https://pkg.go.dev/maps#Keys) returns an iterator over keys in a map. | ||
* [Values](https://pkg.go.dev/maps#Values) returns an iterator over values in a map. | ||
|
||
[pkg.go.dev/maps](https://pkg.go.dev/maps) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"maps" | ||
"slices" | ||
) | ||
|
||
func main() { | ||
numbers := map[string]int{ | ||
"one": 1, | ||
"two": 2, | ||
"three": 3, | ||
"four": 4, | ||
"five": 5, | ||
} | ||
fmt.Printf("numbers = %v\n", numbers) | ||
|
||
// maps.Values | ||
fmt.Printf("\nslices.Sorted(maps.Values(numbers))\n") | ||
sortedValues := slices.Sorted(maps.Values(numbers)) | ||
fmt.Printf("\t%v\n", sortedValues) | ||
|
||
// maps.Keys | ||
fmt.Printf("\nslices.Sorted(maps.Keys(numbers))\n") | ||
sortedKeys := slices.Sorted(maps.Keys(numbers)) | ||
fmt.Printf("\t%q\n", sortedKeys) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Minor changes to the library: `net/http.Request.Pattern` and `slices.Repeat` | ||
|
||
## `net/http.Request.Pattern` | ||
|
||
Excerpt from official release notes: | ||
|
||
> Pattern is the `ServeMux` pattern that matched the request. | ||
> It is empty if the request was not matched against a pattern. | ||
[pkg.go.dev/net/http#Request.Pattern](https://pkg.go.dev/net/http#Request.Pattern) | ||
|
||
## `net/http.Request.Pattern` | ||
|
||
Excerpt from official release notes: | ||
|
||
> Repeat returns a new slice that repeats the provided slice the given number | ||
> of times. | ||
[pkg.go.dev/slices#Repeat](https://pkg.go.dev/slices#Repeat) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package main_test | ||
|
||
import ( | ||
"encoding/json" | ||
"io" | ||
"net/http" | ||
"net/http/httptest" | ||
"slices" | ||
"testing" | ||
) | ||
|
||
func TestMe(t *testing.T) { | ||
mux := http.NewServeMux() | ||
mux.HandleFunc("GET /hi", func(w http.ResponseWriter, req *http.Request) { | ||
// New function: slices.Repeat + http.Request.Pattern | ||
v, _ := json.Marshal(slices.Repeat([]string{req.Pattern}, 2)) | ||
w.Write(v) | ||
}) | ||
|
||
server := httptest.NewServer(mux) | ||
|
||
req, err := http.NewRequest(http.MethodGet, server.URL+"/hi", nil) | ||
if err != nil { | ||
t.Fatalf("new request: %v", err) | ||
} | ||
|
||
client := http.Client{} | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
t.Fatalf("do failed: %v", err) | ||
} | ||
defer resp.Body.Close() | ||
|
||
val, err := io.ReadAll(resp.Body) | ||
if err != nil { | ||
t.Fatalf("do failed: %v", err) | ||
} | ||
|
||
valStr := string(val) | ||
if valStr != `["GET /hi","GET /hi"]` { | ||
t.Fatalf("invalid value: %v", valStr) | ||
} | ||
} |
Oops, something went wrong.