如何检测按键事件

Bla*_*rde 5 go

我的目的是按顺序打印字符串,当用户输入某个字符时,我们暂停进程并读取标准输入内容。我知道可以捕获 os.Interrupt 信号,但我不知道如何捕获标准输入中的事件。我不想扫描并等待用户输入文本。当有按键事件时,该过程停止。

我的问题:如何检测标准输入上的事件?

这是当前的解决方案以及您的建议。Go 例程并不构成最佳解决方案,因为您无法将它们作为线程进行管理。我目前正在继续致力于此工作并随时向您通报最新情况。

func main() {
    quit := make(chan bool)

    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
        fmt.Println("-----------------")
        fmt.Println("Go routine running :", runtime.NumGoroutine())
        go func() {
             select {
                case <-quit:
                return
             default:
                fmt.Println("Text received and changed")
                fmt.Println("-----------------")
                for {
                    timer := time.NewTimer(time.Second * 1)
                    <-timer.C
                    fmt.Println(scanner.Text())
                }
            }

            fmt.Println("Routine closed")
        }()

    }
    if scanner.Err() != nil {
        quit <- false
    }
}
Run Code Online (Sandbox Code Playgroud)

否则,如果我遵循你的解决方案@varius:

func main() {
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    for {
        timer := time.NewTimer(time.Second * 1)
        <-timer.C
        fmt.Println(scanner.Text())
    }
}
if scanner.Err() != nil {
 /*handle error*/
}
}
Run Code Online (Sandbox Code Playgroud)

但我无法在程序运行时更改扫描内容。

KEI*_*NOS 6

不知道它是否会回答您的问题,但对于那些想要确定单个按键而不需要enterkey 的人,如下所示:

$ go run . <enter>
Key press => a
Key press => b
Key press => c
Key press => d
Key press => e
... (ctrl+c)
signal: interrupt
Run Code Online (Sandbox Code Playgroud)

mattngithub.com/mattn/go-tty的模块可能会有所帮助。

$ go run . <enter>
Key press => a
Key press => b
Key press => c
Key press => d
Key press => e
... (ctrl+c)
signal: interrupt
Run Code Online (Sandbox Code Playgroud)
package main

import (
    "fmt"
    "log"

    "github.com/mattn/go-tty"
)

func main() {
    tty, err := tty.Open()
    if err != nil {
        log.Fatal(err)
    }
    defer tty.Close()

    for {
        r, err := tty.ReadRune()
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println("Key press => " + string(r))
    }
}
Run Code Online (Sandbox Code Playgroud)
  • 测试于:
    • 英特尔酷睿 i5,2.7 GHz 双核
    • macOS Catalina 10.15.7、Debian GNU/Linux 10(buster)、Alpine Linux v3.13