从创意到Go语言CLI工具:编写、编译、部署

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么Go是CLI工具的理想语言?



想象一下:你需要编写一个在控制台中运行、处理文件、调用API或只是自动化日常工作的工具。你可以选择Python、Node.js或Bash。但如果速度、二进制文件大小和分发简便性至关重要——你的选择是Go CLI工具。



Go编译成一个静态二进制文件。没有依赖,没有“你安装了Python 3.8吗?”的问题。下载即运行。这使得Golang CLI工具成为DevOps世界的事实标准(想想Docker、Kubernetes、Hugo——它们都是用Go编写的)。



在本文中,我们不仅会讨论理论。我们将从零开始创建一个真正的Go控制台工具,它将解析JSON、与HTTP交互并输出漂亮的表格。你将学习如何构建项目、处理错误以及为任何平台编译。



环境设置和项目结构



在编写代码之前,请确保你已安装Go(版本1.21+)。检查方法很简单:



go version


为我们的项目创建一个目录。将工具命名为json2table——它将从stdin或文件读取JSON,并以表格形式输出数据。



mkdir json2tablecd json2tablego mod init github.com/your-username/json2table


项目结构将是Go开发的经典结构:



  • main.go — 入口点
  • internal/ — 内部逻辑(解析、输出)
  • cmd/ — 命令处理代码(如果使用Cobra)


我们将从简单的开始,不使用框架,然后添加标志和帮助信息。



编写工具核心:JSON解析和表格输出



创建文件internal/parser.go。在这里,我们将解析JSON并将其转换为结构体。



package internal

import ( "encoding/json" "fmt" "io")

// Record表示表格中的一行type Record map[string]interface{}

// ParseJSON从reader读取JSON并返回记录切片func ParseJSON(r io.Reader) ([]Record, error) { var data []Record decoder := json.NewDecoder(r) if err := decoder.Decode(&data); err != nil { return nil, fmt.Errorf("JSON解析错误: %w", err) } return data, nil}


现在创建internal/table.go用于格式化输出:



package internal

import ( "fmt" "strings" "text/tabwriter" "os")

// PrintTable以对齐的表格形式输出记录func PrintTable(records []Record) { if len(records) == 0 { fmt.Println("没有数据可显示") return }

// 收集所有唯一的键(列标题) headers := make([]string, 0) seen := make(map[string]bool) for _, rec := range records { for key := range rec { if !seen[key] { headers = append(headers, key) seen[key] = true } } }

// 使用tabwriter进行美观输出 w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)

// 标题 fmt.Fprintln(w, strings.Join(headers, "\\t"))

// 分隔线 sep := make([]string, len(headers)) for i, h := range headers { sep[i] = strings.Repeat("-", len(h)) } fmt.Fprintln(w, strings.Join(sep, "\\t"))

// 数据 for _, rec := range records { row := make([]string, len(headers)) for i, h := range headers { if val, ok := rec[h]; ok { row[i] = fmt.Sprintf("%v", val) } else { row[i] = "" } } fmt.Fprintln(w, strings.Join(row, "\\t")) }

w.Flush()}


将所有内容整合到main中。

博客

书籍推荐