interact
September 24, 2026 · View on GitHub
interact 提供命令行交互式输入辅助能力。
它包含常见终端交互方法,例如:
ReadInputReadLineReadFirstPromptConfirmQuery/Question/AskSelect/ChoiceMultiSelect/CheckboxReadPasswordCollector和cparam
文档
安装
go get github.com/gookit/cliui/interact
新 UI 层
interact/ui 是一个新的抽象层,用于构建由 backend 驱动的交互组件。
- package:
github.com/gookit/cliui/interact/ui - 当前 backend:
github.com/gookit/cliui/interact/backend/plain - 事件驱动 backend:
github.com/gookit/cliui/interact/backend/readline readline.New()在非 TTY 输入下会回退到plainreadline.NewStrict()在无法使用 TTY 时会直接返回错误,而不是回退Input支持 UTF-8 行编辑和常用快捷键Select和MultiSelect支持禁用项、默认值、导航键和可见的选择状态- 详情:interact-ui.md
interact 包也提供了一组 bridge helper:
NewUIInputNewUIConfirmNewUISelectNewUIMultiSelectNewUIPlainBackendNewUIReadlineBackendNewUIStrictReadlineBackendNewUIFakeBackend
如果测试或应用需要替换 interact、interact/ui、show 和 progress 共享的默认输入/输出流,可以使用根包 github.com/gookit/cliui 提供的辅助方法:
cliui.CustomIO(in, out)
defer cliui.ResetIO()
快速示例
Read Input
ReadInput 用于读取一行普通文本输入,适合简单参数、名称、路径等一次性输入。
name, err := interact.ReadInput("Your name: ")
if err != nil {
panic(err)
}
fmt.Println("name:", name)
效果示例:
Your name: tom
name: tom
Prompt
Prompt 支持上下文控制和默认值,适合需要可取消、可超时或统一管理上下文的输入流程。
answer, err := interact.Prompt(context.Background(), "Environment", "dev")
if err != nil {
panic(err)
}
fmt.Println("env:", answer)
效果示例:
Environment [dev]: prod
env: prod
Confirm
Confirm 用于确认类问题,返回布尔值,适合删除、覆盖、部署等需要用户确认的操作。
ok, err := interact.Confirm("Continue? ", true)
if err != nil {
panic(err)
}
if ok {
fmt.Println("confirmed")
}
效果示例:
Continue? [Y/n] y
confirmed
Question
Question/Ask 用于带默认值和可选校验的问题输入,适合声明式地组织单个问题。
name, err := interact.Ask("Your name?", "guest", nil)
if err != nil {
panic(err)
}
fmt.Println("name:", name)
需要配置或复用问题时,可以使用 NewQuestion:
value, err := interact.NewQuestion("Your name?", "guest").Run()
if err != nil {
panic(err)
}
fmt.Println(value.String())
效果示例:
Your name? [guest]: tom
tom
Select
Select 用于从多个候选项中选择一个值,适合环境、区域、模板、操作类型等单选场景。
city, err := interact.SelectOne(
"Your city?",
[]string{"chengdu", "beijing", "shanghai"},
"",
)
if err != nil {
panic(err)
}
fmt.Println("city:", city)
效果示例:
Your city?
1) chengdu
2) beijing
3) shanghai
Please select: 1
city: chengdu
Multi Select
Multi Select 用于选择多个值,适合批量启用模块、选择服务、选择标签等多选场景。
services, err := interact.MultiSelect(
"Choose services",
[]string{"api", "worker", "web"},
[]string{"api"},
)
if err != nil {
panic(err)
}
fmt.Println("services:", services)
效果示例:
Choose services
1) api
2) worker
3) web
Please select: 1,3
services: [api web]
需要同时获取选中项的 key 和 value 时,可以直接使用 NewSelect:
s := interact.NewSelect("Choose env", []string{"dev", "prod"})
result, err := s.Run()
if err != nil {
panic(err)
}
fmt.Println(result.KeyString(), result.String())
Password
ReadPassword 用于读取敏感输入,终端中不会回显实际内容。
password := interact.ReadPassword("Password: ")
fmt.Println("password length:", len(password))
效果示例:
Password:
password length: 8
Collector
Collector 可以组合多个输入参数并按顺序执行:
c := interact.NewCollector()
err := c.AddParams(
cparam.NewStringParam("name", "Your name"),
cparam.NewChoiceParam("env", "Choose env").WithChoices([]string{"dev", "prod"}),
)
if err != nil {
panic(err)
}
效果示例:
Your name: tom
Choose env
1) dev
2) prod
Please select: 2
UI Bridge
如果希望使用新的 interact/ui 组件,但不直接引入子包,可以使用 bridge helper:
be := interact.NewUIReadlineBackend()
name, err := interact.NewUIInput("Your name").Run(context.Background(), be)
if err != nil {
panic(err)
}
fmt.Println("name:", name)
效果示例:
Your name: tom
name: tom
完整 Select 示例
package main
import (
"fmt"
"github.com/gookit/color"
"github.com/gookit/cliui/interact"
)
func main() {
color.Green.Println("This's An Select Demo")
fmt.Println("----------------------------------------------------------")
ans, err := interact.SelectOne(
"Your city name(use string slice/array)?",
[]string{"chengdu", "beijing", "shanghai"},
"",
)
if err != nil {
panic(err)
}
color.Info.Println("your select is:", ans)
fmt.Println("----------------------------------------------------------")
ans1, err := interact.Choice(
"Your age(use int slice/array)?",
[]int{23, 34, 45},
"",
)
if err != nil {
panic(err)
}
color.Info.Println("your select is:", ans1)
fmt.Println("----------------------------------------------------------")
ans2, err := interact.SingleSelect(
"Your city name(use map)?",
map[string]string{"a": "chengdu", "b": "beijing", "c": "shanghai"},
"a",
)
if err != nil {
panic(err)
}
color.Info.Println("your select is:", ans2)
s := interact.NewSelect("Your city", []string{"chengdu", "beijing", "shanghai"})
s.DefOpt = "2"
r, err := s.Run()
if err != nil {
panic(err)
}
color.Info.Println("your select key:", r.K.String())
color.Info.Println("your select val:", r.String())
}
预览:
