代码之家  ›  专栏  ›  技术社区  ›  kramer65

如何在不进入果朗循环的情况下捕捉按键

  •  2
  • kramer65  · 技术社区  · 7 年前

    我有一个循环,其中有些事情是根据它运行的状态发生的(手动/自动/学习)。我现在想让程序在这些状态之间切换,按下键盘上的相应字母(“M”表示手动,“A”表示自动,“L”表示学习)。

    因此,要做到这一点,我需要能够捕捉一个在循环期间的按键,并相应地改变变量状态。我现在有了下面的程序,它可以在按下键后按回车键:

    ch := make(chan string)
    go func(ch chan string) {
        reader := bufio.NewReader(os.Stdin)
        for {
            s, _ := reader.ReadString('\n')
            ch <- s
        }
    }(ch)
    
    for {
        select {
            case stdin, _ := <-ch:
                fmt.Println("Keys pressed:", stdin)
            default:
                fmt.Println("Working..")
        }
        time.Sleep(time.Second)
    }
    

    但我需要按回车键这一事实是不可接受的。

    有没有人知道一种无阻塞的方法来捕捉一个普通字母(不是sigint)的按键,而无需点击enter键?

    2 回复  |  直到 7 年前
        1
  •  1
  •   noamt CoderYL    7 年前

    因为你在用 ReadString 在你的例子中,它期望你给出的任何参数- return 关键。 根据 the docs :

    readstring读取直到输入中第一次出现delim, 返回一个字符串,该字符串包含 定界符。

    这意味着在你点击 返回 关键。

    你可以用普通的 Read 方法来读取所需的字符。 也看这个 Stackoverflow question 供参考。

        2
  •  0
  •   kramer65    7 年前

    好的,在阅读了os.stdin.read()和查找 this answer 我创建了以下代码:

    package main
    
    import (
        "fmt"
        "os"
        "time"
        "os/exec"
    )
    
    func main() {
        ch := make(chan string)
        go func(ch chan string) {
            // disable input buffering
            exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
            // do not display entered characters on the screen
            exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
            var b []byte = make([]byte, 1)
            for {
                os.Stdin.Read(b)
                ch <- string(b)
            }
        }(ch)
    
        for {
            select {
                case stdin, _ := <-ch:
                    fmt.Println("Keys pressed:", stdin)
                default:
                    fmt.Println("Working..")
            }
            time.Sleep(time.Millisecond * 100)
        }
    }
    

    这就像一个魅力,所以我只是张贴给任何未来的读者。

    不管怎样,祝你有个美好的一天!