【发布时间】:2018-02-16 17:10:57
【问题描述】:
我正在用 Go 创建一个简单的基于控制台的游戏。我想要某种方式来接受无缓冲的输入(例如,您输入一个键并立即返回)。我从这段代码开始:
func InitInput() {
exec.Command("stty", "-f", "/dev/tty", "cbreak", "min", "1").Run()
exec.Command("stty", "-f", "/dev/tty", "-echo").Run()
}
func StopInput() {
exec.Command("stty", "-f", "/dev/tty", "echo").Run()
}
func GetInput() string {
var b []byte = make([]byte, 1)
for {
os.Stdin.Read(b)
return string(b)
}
}
这太棒了,但它只适用于基于 *nix 的操作系统,并且需要 3 个函数。接下来,有人为我推荐了这段代码:
/*
// Works also for 64 bits
#ifdef _WIN32
// Lib for console management in windows
#include "conio.h"
#else
// Libs terminal management in Unix, Linux...
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
// Implement reading a key pressed in terminal
char getch(){
char ch = 0;
struct termios old = {0};
fflush(stdout);
if( tcgetattr(0, &old) < 0 ) perror("tcsetattr()");
old.c_lflag &= ~ICANON;
old.c_lflag &= ~ECHO;
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if( tcsetattr(0, TCSANOW, &old) < 0 ) perror("tcsetattr ICANON");
if( read(0, &ch,1) < 0 ) perror("read()");
old.c_lflag |= ICANON;
old.c_lflag |= ECHO;
if(tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON");
return ch;
}
#endif
*/
import "C"
然后你只需要 1 个函数:
func GetInput() string {
return string(byte(C.getch()))
}
这很好用,除了因为 cgo 的工作方式,它非常慢,这对于游戏来说并不理想。此外,用于测试换行符的原始代码 if extras.GetInput() == "\n" {} 不再起作用。有没有办法让单字符无缓冲输入管理器在 Go 中工作而无需使用又大又厚的外部库?
【问题讨论】:
-
你的意思是像github.com/nsf/termbox-go?
-
@icza 这正是我不想要的一个例子。这是一个庞大而臃肿的库,我只需要一个轻量级的输入管理器。
-
go 编译器不包含很多你从导入包中不使用的东西,所以我不认为这是一个问题。
-
而且 termbox-go 相当轻量级:“Termbox 是一个提供简约 API 的库……”
-
@KavehShahbazian 我再次不想要
termbox-go。阅读this。