Use the go language to simply simulate Python's generator _golang

Source: Internet
Author: User
Def demo_input_and_output ():
  input = Yield ' What is the input? '
  Yield ' input is:%s '% input

gen = Demo_input_and_output ()
print (Gen.next ())
print (Gen.send (42))

This code demonstrates the functionality of the Python generator. Can see yield at the same time do two operations, one is to send out the data "waht is the input", at the same time do the operation is to receive data input. And the operation that receives the data is a blocking operation, if the external call to next (that is, to pass none), or call Send (42) (that is, to pass the value of 42), then the blocking operation will wait.

That is to say, Python's generator has a channel of external communication for sending and receiving messages. That's what it says when you use go to simulate Python's generator.

Copy Code code as follows:
Package Main

Import "FMT"

Func Demoinputandoutput (Channel Chan string) {
Channel <-"What Is my input?"
Input: = <-Channel
Channel <-FMT. Sprintf ("Input is:%s", input)
}

Func Main () {
Channel: = Make (Chan string)
Go Demoinputandoutput (channel)
Fmt. PRINTLN (<-Channel)
Channel <-"42"
Fmt. PRINTLN (<-Channel)
}

This code is basically equivalent to the Python version. The implied channel becomes explicit in the go version. Yield became a channel <-operation, and immediately made a <-channel blocking read operation. This is the essence of yield.

The Go channel can also be used as a iterator for loops:

Copy Code code as follows:
package main

Import "FMT"

Func somegenerator () <-chan str ing {
    channel: = Make (chan string)
    go func () {
         Channel <-"A"
        FMT. Println ("After a")
        channel <-"C"
         FMT. Println ("After C")
        channel <-"B"
         FMT. Println (' after B ')
        Close (channel)
   } ()
    return Channel
}

Func main () {
    channel: = Somegenerator ()
  ;   for Val: = Range Channel {
        fmt. Println (val)
   }
}

Unlike Python's yield, where the channel <-is not equivalent to yield, it goes down until it blocks. Effect is

Copy Code code as follows:
After a
A
C
After C
After B
B

This is not the same order as expected. Here does not have after a after C B are printed because channel default only one element of the buffer, so write a block. If you increase the buffer, then it works.

Copy Code code as follows:
Make (Chan string, 10)

The output becomes:

After a after
C b
a
c
b

It can be seen that Goroutine is like an independent thread playing with itself, without waiting to be executed. If you want to simulate yield, add the synchronized operation shown (blocking the read signal from the channel):

Copy Code code as follows:
Package Main

Import "FMT"

Func somegenerator () Chan string {
Channel: = Make (Chan string)
Go func () {
Channel <-"a"
<-Channel
Fmt. Println ("After a")
Channel <-"C"
<-Channel
Fmt. Println ("After C")
Channel <-"B"
<-Channel
Fmt. Println ("after B")
Close (channel)
}()
Return Channel
}

Func Main () {
Channel: = Somegenerator ()
For Val: = Range Channel {
Fmt. Println (Val)
Channel <-""
}
}

The result of the output is

A after the
a
c after
c
b


Here we can see that Python's generator is like a Golang goroutine with a channel with no buffer. This results in a yield context switch each time a value is generated. Although the process context switch is inexpensive, it is not without cost. Such a design as Goroutine's buffered channel can allow a goroutine to generate some output at once and then block the wait, instead of producing an output that blocks the wait and then produces another output. Golang rocks!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.