Golang中处理Todo列表的JSON问题求助
Golang中处理Todo列表的JSON问题求助
我正在开发一个基于命令行界面的待办事项列表应用程序,它使用类似这样的命令:sloth add -m "message"。我的应用程序将任务消息、ID和时间存储为JSON文件,如下所示:
{
"TaskID":"aa9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy a milk","TaskTime":"1530979782"
}
每次执行sloth add -m "msg"命令时,数据都必须存储到JSON文件中,如下所示:
{
"TaskID":"aa9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy a milk","TaskTime":"1530979782",
"TaskID":"ee9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy butter","TaskTime":"1530979785"
}
如何将一个任务和其他任务追加到前一个任务之后或第一个任务之上?
更多关于Golang中处理Todo列表的JSON问题求助的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你是否已经完整阅读了Go语言官方教程?https://tour.golang.org/welcome/1
关于切片的使用方法在此处有详细说明:https://tour.golang.org/moretypes/7,但我建议你先通读整个教程指南,其中包含大量实用信息。
你是如何存储JSON数据的?你正在存储JSON吗?你需要将列表保存在某个位置,并在程序每次启动时重新读取它。
更多关于Golang中处理Todo列表的JSON问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我不太理解你的备注,但是否有理由要嵌套对象?这只是在不需要的地方增加了复杂性。
一般工作流程应该如下:
- 检查文件是否存在,如果不存在则用空的JSON数组或对象初始化它,具体取决于你最终决定使用什么
- 读取文件并解组到你的Go切片/结构体中
- 将新的待办事项添加到正确的位置
- 将Go数据写回JSON文件
{
"task": [ {"TaskID":"aa9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy a milk","TaskTime":"1530979782"},
{"TaskID":"c1f9b0be6951cd25814c80cd8bd29228ba6eb5b9","TaskMsg":"buy butter","TaskTime":"1530979785"}
]
}
你好,这是正确的。我该如何使用 [] T 来处理这个数组?因为添加一个任务后应用程序就会退出,再次执行命令时它仍然能正常工作,这个我已经实现了。我需要实现数组追加功能。
后面的JSON对象中存在重复的键。同一个键的最后一次出现会覆盖之前的值,因此你后面的示例实际上等同于:
{
"TaskID":"ee9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy butter","TaskTime":"1530979785"
}
我认为你真正需要的是JSON数组:
[
{"TaskID":"aa9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy a milk","TaskTime":"1530979782"},
{"TaskID":"ee9bb19240b1caf0e2a0ec2f6f561874f9140207","TaskMsg":"buy butter","TaskTime":"1530979785"}
]
这很容易实现,只需要使用类型为[]T的变量,其中T是你原来的结构体类型。
我猜你已经知道如何向切片追加元素,但如果你不清楚的话,欢迎随时提问。
在Go语言中,JSON对象要求键必须是唯一的,因此您当前的数据结构是不正确的。您应该使用JSON数组来存储多个任务。以下是正确的实现方法:
首先,定义任务结构体:
type Task struct {
TaskID string `json:"TaskID"`
TaskMsg string `json:"TaskMsg"`
TaskTime string `json:"TaskTime"`
}
读取现有任务并追加新任务的完整示例:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"time"
"crypto/sha1"
"strconv"
)
func main() {
filename := "tasks.json"
// 读取现有任务
tasks := readTasks(filename)
// 创建新任务
newTask := Task{
TaskID: generateTaskID(),
TaskMsg: "buy butter",
TaskTime: strconv.FormatInt(time.Now().Unix(), 10),
}
// 追加新任务
tasks = append(tasks, newTask)
// 写回文件
writeTasks(filename, tasks)
}
func readTasks(filename string) []Task {
var tasks []Task
// 检查文件是否存在
if _, err := os.Stat(filename); os.IsNotExist(err) {
return tasks
}
// 读取文件内容
data, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Printf("读取文件错误: %v\n", err)
return tasks
}
// 解析JSON
if len(data) > 0 {
err = json.Unmarshal(data, &tasks)
if err != nil {
fmt.Printf("解析JSON错误: %v\n", err)
}
}
return tasks
}
func writeTasks(filename string, tasks []Task) {
// 转换为JSON
data, err := json.MarshalIndent(tasks, "", " ")
if err != nil {
fmt.Printf("JSON编码错误: %v\n", err)
return
}
// 写入文件
err = ioutil.WriteFile(filename, data, 0644)
if err != nil {
fmt.Printf("写入文件错误: %v\n", err)
return
}
fmt.Println("任务已成功添加到文件")
}
func generateTaskID() string {
hash := sha1.New()
hash.Write([]byte(strconv.FormatInt(time.Now().UnixNano(), 10)))
return fmt.Sprintf("%x", hash.Sum(nil))
}
最终的JSON文件格式将是:
[
{
"TaskID": "aa9bb19240b1caf0e2a0ec2f6f561874f9140207",
"TaskMsg": "buy a milk",
"TaskTime": "1530979782"
},
{
"TaskID": "ee9bb19240b1caf0e2a0ec2f6f561874f9140207",
"TaskMsg": "buy butter",
"TaskTime": "1530979785"
}
]
对于命令行参数处理,可以使用以下示例:
func addTask(message string) {
filename := "tasks.json"
tasks := readTasks(filename)
newTask := Task{
TaskID: generateTaskID(),
TaskMsg: message,
TaskTime: strconv.FormatInt(time.Now().Unix(), 10),
}
tasks = append(tasks, newTask)
writeTasks(filename, tasks)
}
这样每次执行sloth add -m "msg"命令时,都会将新任务追加到JSON数组中,保持正确的数据结构。

