今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《如何在Golang循环中捕获按键而不输入》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!
问题内容我有一个循环,其中一些事情根据它运行的状态(手动/自动/学习)发生。我现在希望能够通过按键盘上的相应字母(“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 键吗?
解决方案
在阅读了 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)
}
}
这就像一个魅力。
如果你想检查是否按下了某个键而不阻塞它所在的进程,你应该使用这样的东西:
import (
...
"golang.org/x/sys/windows"
)
var user32_dll = windows.NewLazyDLL("user32.dll")
var GetKeyState = user32_dll.NewProc("GetKeyState")
func wasESCKeyPressed() bool {
r1, _, _ := GetKeyState.Call(27) // Call API to get ESC key state.
return r1 == 65409 // Code for KEY_UP event of ESC key.
}
func loop() {
for {
// Do something...
if wasESCKeyPressed() {
break
}
// Do something...
time.Sleep(time.Millisecond * 10)
}
}
今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注编程网公众号,一起学习编程~