Golang中结构体无法完整打印JSON数据的解决方法

Golang中结构体无法完整打印JSON数据的解决方法 大家好,

有人能帮我修复这个程序吗?它运行正常但输出错误。 我有一个结构体,当我运行这个程序时,它打印出:

输出:{todo {0001-01-01 00:00:00 +0000 UTC Assad lunch from home false}}

而不是 输出:{todo {0001-01-01 00:00:00 +0000 UTC Assad lunch from home today false 3 pm}}

以下是代码:

package main

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

type ServiceStruct struct {
	Todo string `json:"todo"`

	DataStruct struct {
		CreationDateTime    time.Time `json:"creation_dt"`
		Title               string    `json:"title"`
		Description         string    `json:"description"`
		DueDateTime         string    `json:"due_date_time"`
		CompletionDateTime  string    `json:"completion_date_time"`
		CompletionStatus    bool      `json:"completion_status"`
	}
}

func main() {

	x := `{
	"Todo": "todo",
"DataStruct": {
"CreationDateTime": "time.Now()",
    "Title":   "Assad",
	"Description": "lunch from home",
	"DueDateTime": "today",
	"CompletionStatus": false,
	"CompletionDateTime": "3 pm"
}
}`

	ex := ServiceStruct{}
	json.Unmarshal([]byte(x), &ex)

	fmt.Println(ex)
}

更多关于Golang中结构体无法完整打印JSON数据的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

明白了,谢谢你们的帮助 @NobbZ @Hultan

更多关于Golang中结构体无法完整打印JSON数据的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我该如何解决这个问题?你能帮帮我吗

修复您使用的键。要么让JSON匹配您的结构体定义,要么让结构体匹配您想要使用的键。

在你的类型定义中,你指定的JSON键与实际JSON中使用的不同。修复这些问题(并省略一些明显不是time.Time类型的字段)后,它就能按预期工作了。

在你的结构体定义中,你使用 json:"foo" 来设置要使用的键名,但在要解析的 JSON 中,你却使用了结构体的字段名。

我使用了与结构体中定义的相同的键来初始化x,即使我改变顺序,结果仍然相同。

结构体:

DataStruct struct {
CreationDateTime   	time.Time `json:"creation_dt"`
Title 			string    `json:"title"`
Description  		string    `json:"description"`
DueDateTime  		string    `json:"due_date_time"`
CompletionDateTime  	string    `json:"completion_date_time"`
CompletionStatus 	bool      `json:"completion_status"`
}
x := `{
“Todo”: “todo”,
“DataStruct”: {
“CreationDateTime”: “time.Now()”,
“Title”:   “Assad”,
“Description”: “lunch from home”,
“DueDateTime”: “today”,
“CompletionStatus”: false,
“CompletionDateTime”: “3 pm”
}

我相当确定,在 json: 后面输入的任何内容都必须与 JSON 字符串中的名称(x)匹配。例如,如果你输入 json:creation_dt,那么 JSON 字符串必须包含一个名为 creation_dt 的字段。见下文:

struct: DataStruct struct { CreationDateTime time.Time json:"creation_dt" Title string json:"title" Description string json:"description" DueDateTime string json:"due_date_time" CompletionDateTime string json:"completion_date_time" CompletionStatus bool json:"completion_status" }

x := `{ “Todo”: “todo”, “DataStruct”: { “creation_dt”: “time.Now()”, “title”: “Assad”, “description”: “lunch from home”, “due_date_time”: “today”, “completion_status”: false, “completion_date_time”: “3 pm” }

问题在于JSON字符串中的CreationDateTime字段值是字符串"time.Now()",而不是有效的时间格式。Go的json.Unmarshal无法将其解析为time.Time类型,导致该字段被设置为零值(0001-01-01 00:00:00)。同时,由于DueDateTimeCompletionDateTime字段在结构体中定义为string类型,它们可以正常解析,但在打印结构体时,默认的fmt.Println输出不会显示所有字段(特别是当字段值为空字符串时)。

要完整打印JSON数据,建议使用json.Marshal将结构体转换回JSON格式并打印。以下是修改后的代码:

package main

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

type ServiceStruct struct {
	Todo string `json:"todo"`

	DataStruct struct {
		CreationDateTime    time.Time `json:"creation_dt"`
		Title               string    `json:"title"`
		Description         string    `json:"description"`
		DueDateTime         string    `json:"due_date_time"`
		CompletionDateTime  string    `json:"completion_date_time"`
		CompletionStatus    bool      `json:"completion_status"`
	}
}

func main() {
	// 使用有效的时间格式字符串,例如RFC3339
	x := `{
	"Todo": "todo",
	"DataStruct": {
		"CreationDateTime": "2023-10-05T14:30:00Z",
		"Title":   "Assad",
		"Description": "lunch from home",
		"DueDateTime": "today",
		"CompletionStatus": false,
		"CompletionDateTime": "3 pm"
	}
}`

	ex := ServiceStruct{}
	err := json.Unmarshal([]byte(x), &ex)
	if err != nil {
		fmt.Println("JSON解析错误:", err)
		return
	}

	// 将结构体转换回JSON并缩进打印,以显示所有字段
	jsonData, err := json.MarshalIndent(ex, "", "  ")
	if err != nil {
		fmt.Println("JSON生成错误:", err)
		return
	}
	fmt.Println(string(jsonData))
}

输出将包含所有字段:

{
  "todo": "todo",
  "DataStruct": {
    "creation_dt": "2023-10-05T14:30:00Z",
    "title": "Assad",
    "description": "lunch from home",
    "due_date_time": "today",
    "completion_date_time": "3 pm",
    "completion_status": false
  }
}

如果必须使用原始JSON字符串中的"time.Now()",则需要自定义time.Time的解析逻辑。例如,通过实现json.Unmarshaler接口:

type CustomTime struct {
	time.Time
}

func (ct *CustomTime) UnmarshalJSON(b []byte) error {
	s := string(b)
	if s == `"time.Now()"` {
		ct.Time = time.Now()
		return nil
	}
	// 否则尝试标准时间格式解析
	return json.Unmarshal(b, &ct.Time)
}

// 修改结构体字段类型
type ServiceStruct struct {
	Todo string `json:"todo"`
	DataStruct struct {
		CreationDateTime    CustomTime `json:"creation_dt"`
		Title               string     `json:"title"`
		// 其他字段保持不变
	}
}

这样即可处理特殊字符串"time.Now()",同时正常解析标准时间格式。

回到顶部