如何使用go例程和term ui退出我的go代码

时间:2017-07-26 18:57:54

标签: go command-line-interface

我最近开始学习go,我对所有功能印象非常深刻。我一直在玩惯例和term-ui并面临一些麻烦。我试图在运行它之后从控制台退出此代码,但它只是没有响应。如果我在没有常规例程的情况下运行它,它会响应我的2按键事件。

感谢任何帮助。

我的代码

q

1 个答案:

答案 0 :(得分:1)

这可能是您正在寻找的答案。首先,您没有正确使用termui。您需要调用它的Loop函数来启动Event循环,以便它实际上可以开始侦听q密钥。 Loop被称为last,因为从那时起它基本上控制了主goroutine,直到调用StopLoop并退出。

为了阻止goroutines,通常会有一个"停止"渠道。通常它是chan struct{}以节省内存,因为您不必在其中放置任何内容。无论你希望goroutine可能停止和关闭(或者做其他事情),你都可以使用select语句和你正在使用的channel。这个select是有序的,因此除非它们阻止,否则它们将按顺序从它们开始,在这种情况下它会尝试下一个,因此stop channel通常是第一个。 stop频道通常会阻止,但为了让它采用此路径,只需close()它就会导致在select中选择此路径。所以我们在close()键盘处理程序中q

package main

import (
    "fmt"
    "github.com/gizak/termui"
    "strconv"
    "time"
)

func getData(ch chan string, stop chan struct{}) {
    i := 0
    for {
        select {
        case <-stop:
            break
        case ch <- strconv.Itoa(i):
        }
        i++
        time.Sleep(time.Second)
        if i == 20 {
            break
        }
    }
}

func Display(ch chan string, stop chan struct{}) {

    for {
        var elem string
        select {
        case <-stop:
            break
        case elem = <-ch:
        }
        par := termui.NewPar(elem)
        par.Height = 5
        par.Width = 37
        par.Y = 4
        par.BorderLabel = "term ui example with chan"
        par.BorderFg = termui.ColorYellow
        termui.Render(par)
    }
}

func main() {
    ch := make(chan string)
    stop := make(chan struct{})
    err := termui.Init()
    if err != nil {
        panic(err)
    }
    defer termui.Close()
    termui.Handle("/sys/kbd/q", func(termui.Event) {
        fmt.Println("q captured")
        close(stop)
        termui.StopLoop()
    })
    go getData(ch, stop)
    go Display(ch, stop)
    termui.Loop()
}