range-over-func in Go

WBOY
Release: 2024-08-19 04:42:32
Original
508 people have browsed it

range-over-func in Go

Go1.23 has brought the range-over-func feature that was an experiment in go1.22 to be used for real. If anyone has read the sample code, you may have to meditate for a long time. bit Don't do that. P'Yod will explain in a very simple way for you to read

Starting from the spec of For statements with range clause, 3 types of Expressions have been added:

func(func() bool)
func(func(V) bool)
func(func(K, V) bool)
Copy after login

I would like to add one variable to explain as follows

f func(yield func() bool)
f func(yield func(V) bool)
f func(yield func(K, V) bool)
Copy after login

The spec says that when we use the function f as an expression in rage, every time we call the yield function there before finishing the function f, we get the result in each loop. Equal to the value we inserted into the yield. I'm still confused when I explain it. Better write code

func main() {
    for range loop {
        fmt.Println("-")
    }
}

func loop(yield func() bool) {
    yield()
    yield()
}
Copy after login

output:

-
-
Copy after login

If we write code like this, we will get 2 complete loops because we call yield 2 times in f according to the spec, here we name it loop and it will not return anything to us. Because we choose to use a pattern with a yield that doesn't accept any arguments

Another example

func main() {
    for i := range loop {
        fmt.Println(i)
    }
}

func loop(yield func(int) bool) {
    yield(3)
    yield(7)
}
Copy after login

output:

3
7
Copy after login

Like this we will get 2 rounds as well because we called yield once and now range will return 2 values ​​which are 3 and 7 which we use to call yield each time

Another example

func main() {
    for i := range loop {
        fmt.Println(i)
    }
}

func Loop(yield func(int, string) bool) {
    yield(3, "three")
    yield(5, "five")
    yield(7, "seven")
}
Copy after login

output:

3 three
5 five
7 seven
Copy after login

We will get 3 loops and get 2 values ​​each time according to the yield we put in each time
And we can also call yield by inserting any type of arguments such as

func loop(yield func(string, bool) bool) {
    yield("three", true)
    yield("five", false)
    yield("seven", false)
}
Copy after login

Now that we understand the mechanism of it. When we read difficult examples, we will understand more, such as the example in the Go Wiki: Rangefunc Experiment

package slices

func Backward[E any](s []E) func(func(int, E) bool) {
    return func(yield func(int, E) bool) {
        for i := len(s)-1; i >= 0; i-- {
            if !yield(i, s[i]) {
                return
            }
        }
    }
}
Copy after login

main

s := []string{"hello", "world"}
for i, x := range slices.Backward(s) {
    fmt.Println(i, x)
}
Copy after login

Easier to read, right? In the end, how to apply it is up to you. We only look at how many times the yield is called. You will only get it when you put it in range
The value that will come out is the value dropped into the yield. That's it. End

The above is the detailed content of range-over-func in Go. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!