Go Chronicles

Go Release 1.23

Go 1.23 release has arrived. It comes with some cool new feautres. We are going to discuss the (probably) two most important ones.

Function as iterations

Novelty in the language is the “function as iterations” are accepted for range, in these forms:

func(func() bool)
func(func(K) bool)
func(func(K, V) bool)

It sounds like no big deal, especially for people who have been working with JS for a long time and are used to its convenient closures. However, this can be a huge step in Go language development. The biggest difference it makes is that it enables the developer to iterate through containers (such as maps, arrays, and slices) without exposing the underlying type, as a for-range loop does.

In Go 1.23, there are two types of iterators for different usages: push and pull. A push iterator is the standard supported by for-range loops. It pushes one element to a yield function, which decides if the stop criteria are met. The pull mechanism is more intricate; it provides a handler to the developer, and when it is called, it pulls a value according to the sequence. A detailed explanation of iterators and their usage can be found here.

To illustrate this with an example: suppose we want to find the index of a number in a sorted array(asc) that is smaller than or equal to our given target.

// Old version
	for idx := len(a) - 1; idx >= 0; idx-- {
		if a[idx] <= target {
			fmt.Printf("index found: %d\n", idx)
			break
		}
	}
// New version
	for idx, val := range slices.Backward(a) {
		if val <= target {
			fmt.Printf("index found: %d\n", idx)
			break
		}
	}

See the working example.

Also new in Go 1.23 are functions in the slices and maps packages that work with iterators.

Here are the new functions in the slices package. All and Values are functions that return iterators over the elements of a slice. Collect fetches the values out of an iterator and returns a slice holding those values. See the docs for the others.

Here are the new functions in the maps package. All, Keys, and Values returns iterators over the map contents. Collect fetches the keys and values out of an iterator and returns a new map.

Timer changes: time.Timer & time.Ticker

The Timer and the Ticker also got a facelift. Two main differences has happened. One, as soon as the application does not refer to them they are eligible for garbage collection. Second, their channels are unbuffered, so we know that after Stop() or Reset() no stale activation will occur.

Complete release notes are published here.

Any questions? Feel free to leave them in the comments!

Stay Curious!

Previous
Previous

Triggering(SQL) intensifies