好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > 使用Go語言簡單模擬Python的生成器

使用Go語言簡單模擬Python的生成器

熱門標簽:成都呼叫中心外呼系統平臺 ?兓? 最短的地圖標注 百度地圖標注搜索關鍵詞 電梯外呼訪客系統 谷歌便利店地圖標注 浙江人工智能外呼管理系統 電銷機器人可以補救房產中介嗎 騰訊外呼系統價格
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))

這段代碼演示了 python generator 的功能。可以看到 yield 同時做了兩個操作,一個是往外發數據 "waht is the input",同時做的操作是往里收數據 input。而且這個接收數據的操作是一個阻塞的操作,如果外部沒有調用 next() (也就是往里傳遞None),或者調用send(42)(也就是往里傳遞42這個值),那么這個阻塞的操作就會一直等待下去。

也就是說 python 的 generator 自帶了一個對外通信的 channel,用于收發消息。用 go 模擬 python 的 generator 的話寫起來就是這樣的

復制代碼 代碼如下:
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)
}

這段代碼和 python 版本基本上等價。隱含的 channel 在 go 版本里變成顯式的了。yield 變成了 channel - 操作,同時立馬做了一個 - channel 的阻塞讀操作。這也就是 yield 的本質吧。

go 的 channel 也可以當成 iterator 被 for 循環使用:

復制代碼 代碼如下:
package main

import "fmt"

func someGenerator() -chan string {
    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)
    }
}

和 python 的 yield 不同,這里的 channel - 不等價于 yield,它會往下執行直到阻塞。效果是

復制代碼 代碼如下:
after a
a
c
after c
after b
b

這和預期的順序不一樣。這里沒有把 after a after c after b 都打印出來是因為 channel 默認只有一個元素的buffer,所以寫入了一個就阻塞了。如果增大 buffer,那么就有效果了

復制代碼 代碼如下:
make(chan string, 10)

輸出變成了:

after a
after c
after b
a
c
b

可見 goroutine 就好象一個獨立的線程一樣自己和自己玩去了,不用等待被執行。如果要模擬 yield 就要加上顯示的同步操作(從 channel 里阻塞讀取信號):

復制代碼 代碼如下:
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 - ""
    }
}

輸出的結果就是

a
after a
c
after c
b
after b

到這里我們可以看到,python 的 generator 就好象是 golang 的 goroutine 帶了一個無buffer的channel。這樣導致每次yield一個值,都會產生一次協程上下文切換。雖然協程上下文切換很廉價,但是也不是沒有成本。像 goroutine 的 buffered channel 這樣的設計,可以讓一個 goroutine 一次性多產生一些輸出再阻塞等待,而不是產生一個輸出就阻塞等待一下,再產生另外一個輸出。golang rocks!

您可能感興趣的文章:
  • golang、python、php、c++、c、java、Nodejs性能對比
  • 詳解Golang 與python中的字符串反轉
  • Golang與python線程詳解及簡單實例
  • C++、python和go語言實現的簡單客戶端服務器代碼示例
  • Python和GO語言實現的消息摘要算法示例
  • Golang如何調用Python代碼詳解

標簽:上海 宜昌 眉山 紹興 邢臺 盤錦 七臺河 雅安

巨人網絡通訊聲明:本文標題《使用Go語言簡單模擬Python的生成器》,本文關鍵詞  使用,語言,簡單,模擬,Python,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《使用Go語言簡單模擬Python的生成器》相關的同類信息!
  • 本頁收集關于使用Go語言簡單模擬Python的生成器的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 日本午夜福利片| 一级作爱视频免费观看| chinese老太交视频在线观看| 日产免费自线一二区| 91肉丝酒店高跟| 哺乳期xxxx视频| 贵妃被侍卫扒开双腿H| 韩国一级a毛片视频自拍| 麻豆精产国品一二三产区区别| 爽好舒服宝贝要我小说| AAAAAA片毛片免费观| 久久久噜噜噜久久直播| 啊啊啊用力啊| 国产传媒三级AV精品电影| a级片在线| 国内外精品免费视频| 黑人粗大长爽久久A片| 特极片| 瑶遇见神鹿嘴巴里流口水| 乱人伦电影完整版| 美女张开腿黄网站免费精品动漫 | 亚洲欧美视频一级| 乖把腿张开我要狠狠的要了你| 乱小说欧美综合| 日韩美女网站在线看| 蜜桃在线视频| 强行挺进美艳麻麻体内| 性欧美最新另类| 久久国产精品久久久久久久久久| 色欲av人妻精品一区二区黑牛| 91TV成人片| 桃儿h| 两个人看的日本免费| 狠狠色丁香婷婷综合橹不卡| 97超级碰久久久久香蕉人人| 男女吃奶一进一出动态图| 男女男精品视频站| 肥女巨肥做爰视频XXX| 免费久久人人爽人人爽av| 杨玉环一级A片正在播放1| 精品久久久影院|