Golang中如何访问嵌套结构体
Golang中如何访问嵌套结构体 我编写了一个Go语言程序来从结构体中读取值并显示所需字段的值。
我的Go代码如下
//==================================================================================================
//================================== STRUCT FOR ALL ================================================
type purchaseOrder struct {
PONo string `json:"PONo"`
OrderDate string `json:"OrderDate"`
// ItemQty int `json:"ItemQty"`
ExpDelDate string `json:"ExpDelDate"`
ActualDelDate string `json:"ActualDelDate"`
DeliveryAdd string `json:"DeliveryAdd"`
Status string `json:"Status"`
Amount float64 `json:"Amount"`
Product_lists []Product_Details `json:"Product_lists"`
salesorder salesorder `json:"Salesorder"`
receiptdetails receiptdetails `json:"Receiptdetails"`
invoicedetails invoicedetails `json:"Invoicedetails"`
APAR_Details APAR_Details `json:"apar_details"`
}
type salesorder struct {
SOnum string `json:"SOnum"`
ShipTo string `json:"ShipTo"`
Companyname string `json:"Companyname"`
Address string `json:"Address"`
Quantity int `json:"Quantity"`
Deliverydate string `json:"Deliverydate"`
Unitprice string `json:"Unitprice"`
Value float64 `json:"Value"`
Purchasedate string `json:"Purchasedate"`
}
type receiptdetails struct {
ReceiptNo string `json:"receiptNo"`
Creationdate string `json:"creationdate"`
Status string `json:"status"`
Description string `json:"description"`
}
type invoicedetails struct {
InvoiceNo string `json:"ReceiptNo"`
Invoicedate string `json:"Invoicedate"`
BillTo string `json:"BillTo"`
Item string `json:"Item"`
Amount float64 `json:"Amount"`
}
type Product_Details struct {
ItemNo string `json:"itemNo"`
ItemName string `json:"itemName"`
Quantity int `json:"quantity"`
itemPrice float64 `json:"itemPrice"`
Value float64 `json:"Value"`
}
我编写了一个函数来进行一些验证,函数代码如下:
func (t *Actpay) Validate(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Println("Validate using 3 way matching")
if len(args) != 4 {
return shim.Error("Incorrect Number of arguments.Expecting 4 for validation")
}
// Fetching PO details from ledger
var PoId = strings.ToLower(args[0])
bytes, err := stub.GetState(PoId)
var SoId = strings.ToLower(args[1])
bytes1, err := stub.GetState(SoId)
var RCId = strings.ToLower(args[2])
bytes2, err := stub.GetState(RCId)
var INId = strings.ToLower(args[3])
bytes3, err := stub.GetState(INId)
if err != nil {
return Error(http.StatusInternalServerError, err.Error())
}
var Purchase purchaseOrder
var Receipt receiptdetails
var Invoice invoicedetails
var Sales salesorder
err = json.Unmarshal(bytes, &Purchase)
err = json.Unmarshal(bytes1, &Sales)
err = json.Unmarshal(bytes2,&Receipt)
err = json.Unmarshal(bytes3, &Invoice)
if (Receipt.Status == "Delivered" && Invoice.Amount == Sales.Value && Sales.Value == Purchase.Amount){
return Success(http.StatusCreated, "validated", nil)
} else {
return Error(http.StatusInternalServerError, err.Error())
}
我遇到了以下错误: json: cannot unmarshal array into Go value of type main.salesorder
有人可以建议如何从内部结构体中获取字段吗?
更多关于Golang中如何访问嵌套结构体的实战教程也可以访问 https://www.itying.com/category-94-b0.html
如果我使用
var data interface{}
err := json.Unmarshal(bytes3, &data)
会出现如下错误: 左侧没有新变量可用于 := 不能在 fmt.Printf 参数中使用 data(类型为 interface{})作为字符串类型:需要进行类型断言
更多关于Golang中如何访问嵌套结构体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
err := json.Unmarshal(bytes3, &data)
错误可能是在之前已经声明过,这是导致"左侧:=没有新变量"错误的原因;为了深入了解您的问题所在,如果您方便的话,能否提供完整代码的链接?
根据您提供的信息,似乎 err = json.Unmarshal(bytes3, &Invoice) 这行代码存在一些错误。根据错误信息,bytes3 可能是一个数组。
您可以尝试:
var data interface{}
err := json.Unmarshal(bytes3, &data)
然后检查 data 的值,再定义一个可以通过 json 进行反序列化的结构体。
你好
必须将所有需要从 JSON 填充的字段设置为可导出。也就是说,字段名要以大写字母开头。所以
Product_lists []Product_Details `json:"Product_lists"`
salesorder salesorder `json:"Salesorder"`
receiptdetails receiptdetails `json:"Receiptdetails"`
invoicedetails invoicedetails `json:"Invoicedetails"`
APAR_Details APAR_Details `json:"apar_details"`
}
应该改为
Salesorder salesorder `json:"Salesorder"`
Receiptdetails receiptdetails `json:"Receiptdetails"`
Invoicedetails invoicedetails `json:"Invoicedetails"`
另外为了让其他人更容易阅读你的代码,请在代码前后使用 go 和 将其包裹起来(三个反引号)
package main
import (
"encoding/json"
"log"
)
type invoicedetails struct {
InvoiceNo string `json:"InvoiceNo"`
Invoicedate string `json:"Invoicedate"`
BillTo string `json:"BillTo"`
Item string `json:"Item"`
Amount float64 `json:"Amount"`
}
var body_byte = []byte(`{ "invoiceNo": "IN130", "invoicedate": "2018-11-22T12:16:42.444Z", "billto": "TCS", "item": "Office", "amount": 100 }`)
func main() {
data := &invoicedetails{}
json.Unmarshal(body_byte, &data)
log.Println(data.Item)
}
这段代码在 https://play.golang.org/ 中可以正常运行,但如果在上述帖子中实现相同的代码,会抛出错误:无法将数组解组为 Go 类型 main.invoicedetails
你好,
能否告诉我如何解析嵌套的 JSON?
我的代码是:
package main
import (
"encoding/json"
"log"
)
type purchaseOrder struct {
PONo string `json:"PONo"`
OrderDate string `json:"OrderDate"`
ExpDelDate string `json:"ExpDelDate"`
ActualDelDate string `json:"ActualDelDate"`
DeliveryAdd string `json:"DeliveryAdd"`
Status string `json:"Status"`
Amount float64 `json:"Amount"`
Product_lists []Product_Details `json:"Product_lists"`
}
type Product_Details struct {
ItemNo string `json:"ItemNo"`
ItemName string `json:"ItemName"`
Quantity int `json:"Quantity"`
ItemPrice float64 `json:"ItemPrice"`
Value float64 `json:"Value"`
}
var body_byte = []byte(`[ { "Orderid": "PO160", "Orderdate:": "2018-11-22T10:30:44.790Z", "Expdeldate": "2018-11-22T10:30:44.790Z", "ActualdelDate": "2018-11-22T10:30:44.790Z", "Deliveryadd": "2018-11-22T10:30:44.790Z", "Status": "SO_GENERATED", "Amount": 100, "Product_Details": [ { "ItemNo": "1", "ItemName": "Office", "Quantity": 2, "ItemPrice": 25, "Value": 50 } ] }]`)
func main() {
var data []purchaseOrder
json.Unmarshal(body_byte, &data)
log.Println(data)
}
我已经检查了下面的代码,它运行正常,但在代码中会抛出错误
func (t *Actpay) Validate(stub shim.ChaincodeStubInterface, args []string) peer.Response {
fmt.Println("Validate using 3 way matching")
if len(args) != 4 {
return shim.Error("Incorrect Number of arguments.Expecting 4 for validation")
}
// Fetching PO details from ledger
var PoId = strings.ToLower(args[0])
bytes, err := stub.GetState(PoId)
var SoId = strings.ToLower(args[1])
bytes1, err := stub.GetState(SoId)
var RCId = strings.ToLower(args[2])
bytes2, err := stub.GetState(RCId)
var INId = strings.ToLower(args[3])
bytes3, err := stub.GetState(INId)
if err != nil {
return Error(http.StatusInternalServerError, err.Error())
}
Purchase := &purchaseOrder{}
Sales := &salesorder{}
Receipt := &receiptdetails{}
Invoice := &invoicedetails{}
err = json.Unmarshal(bytes, &Purchase)
err = json.Unmarshal(bytes1, &Sales)
err = json.Unmarshal(bytes2, &Receipt)
err = json.Unmarshal(bytes3, &Invoice)
logger.Debug("Going for validation")
if (Receipt.Status == "Delivered"){
if (Invoice.Amount == Sales.Value){
if (Sales.Value == Purchase.Amount){
return Success(http.StatusOK, "validated", nil)
}else {
return Error(http.StatusInternalServerError, err.Error())
}
}else {
return Error(http.StatusInternalServerError, err.Error())
}
}else {
return Error(http.StatusInternalServerError, err.Error())
}
请建议我如何调试代码或编写错误信息,因为我无法在Swagger UI中调试我的代码。
在Go语言中访问嵌套结构体时,需要使用点操作符来逐级访问内部字段。根据您的代码和错误信息,问题可能出现在JSON数据与结构体类型的匹配上。
以下是访问嵌套结构体字段的正确方式:
// 访问purchaseOrder中的嵌套结构体字段示例
fmt.Printf("Sales Order Number: %s\n", Purchase.salesorder.SOnum)
fmt.Printf("Receipt Status: %s\n", Purchase.receiptdetails.Status)
fmt.Printf("Invoice Amount: %.2f\n", Purchase.invoicedetails.Amount)
// 在您的验证逻辑中,应该这样访问
if (Purchase.receiptdetails.Status == "Delivered" &&
Purchase.invoicedetails.Amount == Purchase.salesorder.Value &&
Purchase.salesorder.Value == Purchase.Amount) {
return Success(http.StatusCreated, "validated", nil)
}
关于您遇到的JSON反序列化错误,问题在于您尝试将数组数据反序列化为单个结构体对象。根据您的purchaseOrder结构体定义,salesorder、receiptdetails和invoicedetails都是单个对象,而不是数组。
检查您的JSON数据格式是否正确:
- 如果JSON中的对应字段是数组,应该使用切片类型
- 如果JSON中的对应字段是对象,使用结构体类型是正确的
例如,如果JSON数据中"Salesorder"是数组,应该修改结构体为:
type purchaseOrder struct {
// ... 其他字段
Salesorder []salesorder `json:"Salesorder"`
// ... 其他字段
}
如果JSON数据中"Salesorder"是单个对象,那么您的结构体定义是正确的,需要确保传入的JSON数据格式匹配。
在验证函数中直接访问嵌套字段:
// 验证嵌套结构体字段
if Purchase.receiptdetails.Status == "Delivered" {
fmt.Println("Receipt status is delivered")
}
if Purchase.invoicedetails.Amount == Purchase.salesorder.Value {
fmt.Printf("Invoice amount %.2f matches sales value %.2f\n",
Purchase.invoicedetails.Amount, Purchase.salesorder.Value)
}
确保JSON数据的结构与您的Go结构体定义完全匹配,这是解决反序列化错误的关键。

