golang使用channel实现ask

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
func ASK(reader io.Reader, writer io.Writer, query string, secret bool) (string, error) {
	if _, err := fmt.Fprint(writer, query+" "); err != nil {
		return "", err
	}
	// 一个信号通道
	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh)
	defer signal.Stop(sigCh)

    // 一个接受错误消息错误通道
	errCh := make(chan error, 1)
	// 读取一行字符消息通道
	lineCh := make(chan string, 1)

	go func() {
		var line string
		var err error
		if secret && isatty.IsTerminal(os.Stdin.Fd()) {
			line, err = speakeasy.Ask("")
		} else {
			r := bufio.NewReader(reader)
			line, err = r.ReadString('\n')
		}
		if err != nil {
			errCh <- err
			return
		}
		lineCh <- strings.TrimRight(line, "\r\n")
	}()

	select {
	case err := <-errCh:
		return "", err
	case line := <-lineCh:
		return line, nil
	case <-sigCh:
		fmt.Fprintln(writer)
		return "", errors.New("interrupted")
	}
}

参考