使用Golang构建简单的命令行任务管理器

使用Golang构建简单的命令行任务管理器

我决定采用边做边学的方法,构建了一个简单的任务管理器命令行工具。过去我曾用JavaScript构建过类似但更小的东西,现在我很高兴能再次(并且更多地使用Go)实现它。您的反馈将不胜感激。

https://github.com/aluyapeter/williamsgov

2 回复

太棒了,Peter… 继续保持出色的工作!!!

更多关于使用Golang构建简单的命令行任务管理器的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


这是一个很棒的Go学习项目!你的任务管理器实现了核心功能,代码结构清晰。以下是一些专业点评和改进建议:

代码亮点

  1. 清晰的模块化结构:将任务管理逻辑分离到task包中是正确的设计选择
  2. JSON持久化:使用标准库的encoding/json处理数据存储很合适
  3. 简单的命令行界面:通过flag包处理命令行参数

可改进的方面

1. 并发安全

当前实现不是并发安全的,多个goroutine同时访问任务列表可能导致数据竞争:

// task/task.go 添加互斥锁保护
package task

import (
    "sync"
)

type TaskManager struct {
    tasks []Task
    mu    sync.RWMutex
}

func (tm *TaskManager) AddTask(description string) {
    tm.mu.Lock()
    defer tm.mu.Unlock()
    // ... 现有逻辑
}

func (tm *TaskManager) ListTasks() []Task {
    tm.mu.RLock()
    defer tm.mu.RUnlock()
    return tm.tasks
}

2. 错误处理增强

当前错误处理可以更完善:

// main.go 改进错误处理
func main() {
    tm, err := task.LoadTasks()
    if err != nil {
        log.Printf("警告: 无法加载任务文件: %v,使用空任务列表", err)
        tm = &task.TaskManager{}
    }
    
    // 命令执行后添加错误检查
    if err := tm.SaveTasks(); err != nil {
        log.Fatalf("保存任务失败: %v", err)
    }
}

3. 使用Cobra或urfave/cli改进CLI

对于更复杂的命令行工具,可以考虑使用成熟的CLI库:

// 使用urfave/cli的示例
import "github.com/urfave/cli/v2"

func main() {
    app := &cli.App{
        Commands: []*cli.Command{
            {
                Name:  "add",
                Usage: "添加新任务",
                Action: func(c *cli.Context) error {
                    return tm.AddTask(c.Args().First())
                },
            },
        },
    }
    app.Run(os.Args)
}

4. 任务过滤和搜索功能

可以添加更多实用功能:

// task/task.go 添加过滤功能
func (tm *TaskManager) FilterTasks(predicate func(Task) bool) []Task {
    tm.mu.RLock()
    defer tm.mu.RUnlock()
    
    var filtered []Task
    for _, t := range tm.tasks {
        if predicate(t) {
            filtered = append(filtered, t)
        }
    }
    return filtered
}

// 使用示例:查找未完成的任务
pending := tm.FilterTasks(func(t task.Task) bool {
    return !t.Completed
})

5. 测试覆盖

添加单元测试确保功能正确性:

// task/task_test.go
func TestTaskManager_AddTask(t *testing.T) {
    tm := &TaskManager{}
    tm.AddTask("测试任务")
    
    if len(tm.ListTasks()) != 1 {
        t.Errorf("期望1个任务,实际得到%d个", len(tm.ListTasks()))
    }
}

性能考虑

  1. 当前每次操作都重写整个JSON文件,对于大量任务可能效率较低
  2. 可以考虑使用更高效的数据存储格式或数据库
  3. 添加任务时使用预分配的切片容量减少内存分配

你的项目是学习Go的绝佳实践,继续完善它会让你更深入理解Go的并发模型、错误处理和项目结构设计。

回到顶部