Golang中嵌套结构体反序列化时出现错误如何解决
Golang中嵌套结构体反序列化时出现错误如何解决 大家好,
有人能帮我看看这个问题吗?当我通过变量赋值时,代码无法正常工作,Unmarshal 报错了。但当我直接使用硬编码值时,却能正常运行。请问有什么具体原因吗?是否有其他方法可以解决这个问题?我正在使用嵌套结构体。以下是我的示例代码。当我对嵌套结构体使用硬编码值时,代码可以正常工作。
package main
import (
"encoding/json"
"fmt"
)
type TestConfig struct {
CId string `json:"cid"`
BSize int `json:"bsize"`
Number int `json:"number"`
LHash string `json:"lhasg"`
MCr string `json:"mcr"`
LId string `json:"lid"`
Fr struct {
FrId string `json:"frid"`
FrAdd string `json:"fradd"`
} `json:"fr"`
Ml struct {
MsId string `json:"msid"`
MsInfo string `json:"msinfo"`
} `json:"ml"`
}
func main() {
var a0, a1 int
var a2, a3, a4, a5, a6, a7, a8, a9 string
a0 = 1000
a1 = 10
a2 = "TestOne"
a3 = "TestTwo"
a4 = "TestThree"
a5 = "TestFour"
a6 = "TestFive"
a7 = "TestSix"
a8 = "TestSeven"
a9 = "TestEight"
jsonConfig := []byte(`{"cid" : a2,
"bsize" : a0,
"number": a1,
"lhash" : a3,
"mcr" : a4,
"lid" : a5,
"fr" :{"frid":a6,
"fradd" :a7},
"masl" :{"msid":a8,
"msinfo":a9}}`)
var config TestConfig
err := json.Unmarshal(jsonConfig, &config)
if err != nil {
panic(err)
}
fmt.Printf("Config: %+v\n", config)
}
更多关于Golang中嵌套结构体反序列化时出现错误如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好 Charles,我认为这正是我一直在寻找的解决方案。我会尝试这个方法并告知你结果。非常感谢!!!
更多关于Golang中嵌套结构体反序列化时出现错误如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好 Charles,实际上我不希望使用硬编码值。我是从另一个接口传递这些值的。这些值应该是动态输入参数。在这种情况下,我应该如何定义它。
在"字符串字面量"中无法识别变量。您需要将JSON对象设置为:{"cid":"TestOne","bsize":1000, ... }。
你好Johan,我没有完全理解你的意思。能否请你详细说明一下?你提到的同名是什么意思?我使用了不同的变量名,比如a0…a9。
如果只是尝试初始化 TestConfig 结构体值,那么可以直接用这些值初始化 jsonConfig。如果是要创建包含配置信息的 JSON 对象,可以这样做:https://play.golang.org/p/xFyavcEfSwK。
在字符串中
`{"cid" : a2,
"bsize" : a0,
等等,其中的值 a2、a0 等不会被替换为同名变量的值。json.Unmarshal 会尝试按原样解析它。
你好Dattatray,
我现在没有时间在论坛上发帖,特别是应要求发帖,但我快速看了一下。
看起来你遇到问题是因为JSON使用了反引号引用,所以字符串字面量的内容无法被Go编译器作为变量名处理。
在Go中有两种字符串字面量。一种使用双引号("),另一种使用反引号()。第一种类型被称为解释型字符串字面量。它被称为解释型是因为可以包含转义序列(实际上,字节值是Go语言规范中使用的术语),比如\n、\0377、\xff或\uaaff,这些会被转换为二进制(在\n的情况下,单个换行符会替换反斜杠和n)。
但当你使用反引号时,它会创建一个原始字符串字面量,字符串内容不会进行任何处理。如果你想给自己找麻烦,只需在很长的Go程序开头附近注释之外插入一个反引号,看看编译器会给你什么。试着把它放在变量或函数名的中间。😄
总之,主要问题是:在你的jsonConfig字节切片中,你提供的是原始字符串字面量。所以编译器无法识别其中的变量名。它根本不会查看这些字符,而是完全按照你写的方式接受字符串字面量。
你可以尝试的一种方法是使用该字符串作为fmt.Sprintf()的格式字符串,将你的变量名替换为printf动词(%s、%d或其他),然后你可以通过这种方式将变量值插入到JSON中。
我甚至不知道Sprintf()是否适用于包含换行符的格式字符串(我从未尝试过),如果不行,那么你需要找到其他方法。如果我给你指错了方向,我表示歉意,而且我现在确实没有时间想出更好的办法。我正在开发一个不涉及JSON的客户端Web应用程序,现在我的思路不适合思考这个问题。所以祝你好运!(顺便说一句,我会在网上寻找Go中JSON编组和解组的任何示例,看看是否有不是愚蠢的"惯用"方法。😁
问题在于你的JSON字符串中直接使用了变量名(如 a2、a0 等),而不是变量的实际值。JSON反序列化需要有效的JSON格式,其中字符串值必须用双引号包围。在你的代码中,a2 等被当作字面字符串处理,而不是变量引用。
以下是修正后的代码,使用 fmt.Sprintf 动态构建JSON字符串:
package main
import (
"encoding/json"
"fmt"
)
type TestConfig struct {
CId string `json:"cid"`
BSize int `json:"bsize"`
Number int `json:"number"`
LHash string `json:"lhasg"`
MCr string `json:"mcr"`
LId string `json:"lid"`
Fr struct {
FrId string `json:"frid"`
FrAdd string `json:"fradd"`
} `json:"fr"`
Ml struct {
MsId string `json:"msid"`
MsInfo string `json:"msinfo"`
} `json:"ml"`
}
func main() {
var a0, a1 int
var a2, a3, a4, a5, a6, a7, a8, a9 string
a0 = 1000
a1 = 10
a2 = "TestOne"
a3 = "TestTwo"
a4 = "TestThree"
a5 = "TestFour"
a6 = "TestFive"
a7 = "TestSix"
a8 = "TestSeven"
a9 = "TestEight"
jsonConfig := fmt.Sprintf(`{"cid":"%s","bsize":%d,"number":%d,"lhash":"%s","mcr":"%s","lid":"%s","fr":{"frid":"%s","fradd":"%s"},"ml":{"msid":"%s","msinfo":"%s"}}`,
a2, a0, a1, a3, a4, a5, a6, a7, a8, a9)
var config TestConfig
err := json.Unmarshal([]byte(jsonConfig), &config)
if err != nil {
panic(err)
}
fmt.Printf("Config: %+v\n", config)
}
另外,我还注意到你的结构体标签中有一个拼写错误:json:"lhasg" 应该是 json:"lhash" 以匹配JSON中的键名。修正后的输出如下:
Config: {CId:TestOne BSize:1000 Number:10 LHash:TestTwo MCr:TestThree LId:TestFour Fr:{FrId:TestFive FrAdd:TestSix} Ml:{MsId:TestSeven MsInfo:TestEight}}
这种方法通过格式化字符串将变量值直接嵌入到JSON字符串中,确保生成有效的JSON格式供反序列化使用。


