在构建命令行工具时,良好的用户交互体验至关重要。尤其是在需要与用户进行复杂输入的场景下,传统的命令行参数和标志可能显得笨拙。 github.com/AlecAivazis/survey/v2 是一个为 Go 语言设计的库,专门用于构建交互式的命令行界面。它提供了多种用户输入方式,让你的 CLI 工具变得更加易用和友好。

一、 survey 是什么?

survey 是一个 Go 库,旨在通过交互式提示收集用户输入。它提供了一组丰富的提示类型,包括文本输入、选择菜单、确认提示、多项选择等,极大地方便了开发者在命令行工具中实现用户交互。

主要功能:

  • 简单易用 :几行代码即可实现复杂的用户交互逻辑。
  • 多种提示类型 :支持文本输入、选择、确认、多选、密码输入等。
  • 验证机制 :提供输入验证功能,确保用户输入的有效性。
  • 默认值与自定义 :支持默认值和高度自定义的提示行为。
  • 二、安装 survey

    要在项目中使用 survey ,首先需要安装它:

    go get -u github.com/AlecAivazis/survey/v2
    

    安装完成后,你可以在项目中导入它:

    import "github.com/AlecAivazis/survey/v2"
    

    三、使用示例

    1. 简单文本输入

    最基础的使用场景是从用户处收集文本输入。比如,我们想询问用户的名字:

    package main
    import (
        "fmt"
        "github.com/AlecAivazis/survey/v2"
    func main() {
        var name string
        prompt := &survey.Input{
            Message: "What is your name?",
        survey.AskOne(prompt, &name)
        fmt.Printf("Hello, %s!\n", name)
    

    在这个例子中,survey.Input 创建了一个文本输入提示,用户的输入将存储在 name 变量中。

    2. 选择菜单

    有时候我们需要用户从一组选项中选择一个。这时可以使用 survey.Select

    var color string
    prompt := &survey.Select{
        Message: "Choose a color:",
        Options: []string{"Red", "Blue", "Green", "Yellow"},
    survey.AskOne(prompt, &color)
    fmt.Printf("You chose %s!\n", color)
    

    survey.Select 会展示一个菜单,用户可以使用上下箭头键进行选择。

    3. 确认提示

    在需要用户确认操作时,可以使用 survey.Confirm

    var confirm bool
    prompt := &survey.Confirm{
        Message: "Do you want to proceed?",
    survey.AskOne(prompt, &confirm)
    if confirm {
        fmt.Println("Proceeding...")
    } else {
        fmt.Println("Operation canceled.")
    

    survey.Confirm 提供了一个简单的 yes/no 提示,适用于操作确认。

    4. 多项选择

    如果需要用户选择多个选项,可以使用 survey.MultiSelect

    var languages []string
    prompt := &survey.MultiSelect{
        Message: "What programming languages do you know?",
        Options: []string{"Go", "Python", "JavaScript", "Rust"},
    survey.AskOne(prompt, &languages)
    fmt.Printf("You selected: %v\n", languages)
    

    在这个例子中,用户可以选择多个编程语言,结果将以切片形式存储。

    5. 密码输入

    对于敏感信息,如密码输入,可以使用 survey.Password,用户的输入不会显示在屏幕上:

    var password string
    prompt := &survey.Password{
        Message: "Enter your password:",
    survey.AskOne(prompt, &password)
    fmt.Println("Password received.")
    

    survey.Password 是处理用户输入敏感信息的理想选择。

    四、输入验证

    survey 还支持对用户输入进行验证,以确保输入符合预期。例如,要求用户输入一个有效的电子邮件地址:

    package main
    import (
        "fmt"
        "github.com/AlecAivazis/survey/v2"
        "strings"
    func main() {
        var email string
        prompt := &survey.Input{
            Message: "Enter your email:",
        survey.AskOne(prompt, &email, survey.WithValidator(survey.Required), survey.WithValidator(func(val interface{}) error {
            if str, ok := val.(string); ok {
                if !strings.Contains(str, "@") {
                    return fmt.Errorf("invalid email address")
            return nil
        fmt.Printf("Email entered: %s\n", email)
    

    在这里,我们使用了 survey.WithValidator 添加自定义验证函数,确保用户输入的内容是有效的电子邮件地址。

    五、结合 Cobra 使用

    survey 常常与 Cobra 结合使用,以创建更复杂的命令行应用程序。例如,你可以在 Cobra 命令的 Run 方法中调用 survey 提示,从而实现交互式的命令参数输入。

    package main
    import (
        "fmt"
        "github.com/spf13/cobra"
        "github.com/AlecAivazis/survey/v2"
    var rootCmd = &cobra.Command{
        Use:   "myapp",
        Short: "MyApp is an interactive CLI application",
        Run: func(cmd *cobra.Command, args []string) {
            var name string
            var age int
            namePrompt := &survey.Input{
                Message: "What is your name?",
            agePrompt := &survey.Input{
                Message: "How old are you?",
            survey.AskOne(namePrompt, &name)
            survey.AskOne(agePrompt, &age)
            fmt.Printf("Hello, %s! You are %d years old.\n", name, age)
    func main() {
        rootCmd.Execute()
    

    这个例子展示了如何在 Cobra 命令中嵌入 survey,为用户提供交互式体验。

    声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
    Author: mengbin
    blog: mengbin
    Github: mengbin92
    cnblogs: 恋水无意
    腾讯云开发者社区:孟斯特