【问题标题】:How to handle infinite go-loops如何处理无限循环
【发布时间】:2016-07-30 11:14:59
【问题描述】:

作为一个爱好项目,我正在开发一个基于"From Events to Futures and Promises and back"alternate futures and promises implementation。原作者在后台使用通道/事件,这就是我使用core.async 的原因。未来,用伪 Go 语法表示,如下所示:

func future(func f() (T, bool)) Future <T> {
    ch = newChannel ()
    spawn(func() {
        x := f()
        for { syncEvt(sndEvt(ch, x)) }
    })
    return rcvEvt(ch)
}

使用有效的 Go 语法、类型定义和 get 函数:

type Comp struct {
    value interface{}
    ok    bool
}

type Future chan Comp

func future(f func() (interface{}, bool)) Future {
    future := make(chan Comp)

    go func() {
        v, o := f()
        c := Comp{v, o}
        for {
            future <- c
        }
    }()

    return future
}

func (ft Future) get() (interface{}, bool) {
    c := <-ft
    return c.value, c.ok
}

现在,当我将它移植到 Clojure 时,我正在考虑按如下方式实现它:

(defrecord Comp [value ok])

(defn future [f]
  (let [future (chan)]
    (go-loop [comp (f)]
      (>! future comp)
      (recur comp))
    future))

(defn get [future]
  (<!! future))

由于我对 Clojure(和 core.async)还很陌生,我担心无限 go-loop。国际奥委会线程会被释放吗?我是否应该提供某种毒丸来停止循环(尽管我认为这很容易出错)?有什么建议吗?

【问题讨论】:

  • 是的,通常recur 是使用if 或其变体之一设置条件的。
  • 我知道,但是论文中的实现使用无限循环来确保一旦comp 可用,future(这是一个通道)总是可用的。因此,我想知道如何在 Clojure 中处理这个问题。

标签: clojure future core.async


【解决方案1】:

Go Clojure 中的块与 Go 中的不同。在 core.async 中,go 块作为附加到通道的回调存在,因此只要通道本身存在,它们就会存在。因此,将 go 块视为回调之上的语法糖,这一切都会变得有意义。

此视频教程更详细:https://www.youtube.com/watch?v=VrwVc-saWLw

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 2012-04-07
    • 2021-08-21
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多