在 Golang 中,结构字面量中的字段名无效。

huangapple go评论90阅读模式
英文:

Invalid field name in struct literal Golang

问题

我有一个名为Status的结构体,里面包含另一个名为Data的结构体。

package model

import "time"

type Status struct {
	Data struct {
		OrderId                   string `json:"orderId"`
		DisputeStatus             string `json:"disputeStatus"`
		DisputeCauseCategoryName  string `json:"disputeCauseCategoryName"`
		ReverseLogisticCost       string `json:"ReverseLogisticCost"`
	} `json:"data"`
	StatusJ string `json:"status"`
}

我有一个函数:

func (s StatusServices) UpdateStatusItem(ctx context.Context, status model.Status) error {
	statusDetails := model.Status{
		Data: status.Data{
			OrderID: status.Data.OrderID,
		},
	}
}

在OrderId中出现了"Invalid field name"错误,我尝试了以下代码:

statusDetails := model.Status{
	Data: status.Data{
		OrderID: status.Data.OrderID,
	},
}

但是它没有起作用,我该怎么办?

英文:

I have this struct call Status and have inside another struct call Data

package model

import "time"

type Status struct {
	Data struct {
        OrderId                   string    json:"orderId"
		DisputeStatus             string    json:"disputeStatus"
		DisputeCauseCategoryName  string    json:"disputeCauseCategoryName"
		ReverseLogisticCost         string        json:"ReverseLogisticCost"
		
	} json:"data"
	StatusJ string json:"status" 
}

And i have this function

func (s StatusServices) UpdateStatusItem(ctx context.Context, status model.Status) (error) {

		statusDetails := model.Status{
			
				OrderID: status.Data.OrderID,
		}

} 

In OrderId appear the error Invalid field name, i tried with this

statusDetails := model.Status{
			Data: status.Data{
				OrderID: status.Data.OrderID,
			},
		}

but i doesn't work, what can i do

答案1

得分: 2

类型model.Status有一个字段Data,其类型定义如下:

struct {
    OrderId                   string    json:"orderId"
    DisputeStatus             string    json:"disputeStatus"
    DisputeCauseCategoryName  string    json:"disputeCauseCategoryName"
    ReverseLogisticCost       string    json:"ReverseLogisticCost"       
}

要初始化这个变量,你可以使用复合字面量,更具体地说是结构体字面量

func main() {
	s := Status{
		Data: struct {
			OrderId                  string `json:"orderId"`
			DisputeStatus            string `json:"disputeStatus"`
			DisputeCauseCategoryName string `json:"disputeCauseCategoryName"`
			ReverseLogisticCost      string `json:"ReverseLogisticCost"`
		}{OrderId: "123456"},
	}
	fmt.Println(s)
}
英文:

The type model.Status has a field Data with a type defined as

struct {
    OrderId                   string    json:"orderId"
    DisputeStatus             string    json:"disputeStatus"
    DisputeCauseCategoryName  string    json:"disputeCauseCategoryName"
    ReverseLogisticCost       string    json:"ReverseLogisticCost"       
}

To initialize the variable, you can use a composite literal, more specifically a struct literal

func main() {
	s := Status{
		Data: struct {
			OrderId                  string `json:"orderId"`
			DisputeStatus            string `json:"disputeStatus"`
			DisputeCauseCategoryName string `json:"disputeCauseCategoryName"`
			ReverseLogisticCost      string `json:"ReverseLogisticCost"`
		}{OrderId: "123456"},
	}
	fmt.Println(s)
}

https://play.golang.org/p/nLhLHNNf7Jb

答案2

得分: 0

我不相信你可以用这种方式初始化一个包含嵌套结构的结构体。

最好的方法是给嵌套结构体定义自己的类型。或者你可以先用一个空的结构体开始(例如 var m model.Status),然后(在另一行中)给 s.Data.OrderId 赋值。

我相信只有在定义和初始化嵌套结构体时可以进行赋值(通常在 Go 的测试中经常这样做),这与这种构造只用于一次性使用的想法是一致的。

英文:

I do not believe you can initialize a struct with a nested struct this way.

Best is to give the nested struct its own type. OR you can start with an empty struct (eg var m model.Status) and then (in a separate line) assign to s.Data.OrderId.

I believe you can only assign to a nested struct if you define and initialize it in one go (as is often done in go tests) which is consistent with the idea that this construct is useful only for onetime off uses.

答案3

得分: 0

不确定是否回答了你的问题,但你可能想要对你的模型进行一些修改,从:

type Status struct {
    Data struct {
        OrderId                   string    json:"orderId"
        DisputeStatus             string    json:"disputeStatus"
        DisputeCauseCategoryName  string    json:"disputeCauseCategoryName"
        ReverseLogisticCost         string        json:"ReverseLogisticCost"
        
    } json:"data"
    StatusJ string json:"status" 
}

改为:

type Status struct {
    Data      Data      `json:"data"`
    StatusJ   string    `json:"status"`
}

type Data struct {
    OrderID                   string    `json:"orderId"`
    DisputeStatus             string    `json:"disputeStatus"`
    DisputeCauseCategoryName  string    `json:"disputeCauseCategoryName"`
    ReverseLogisticCost       string    `json:"reverseLogisticCost"`
}
  • 检查大写字母;在你的示例中,你在Data结构体中有OrderId,但在你的函数中却是status.Data.OrderID
  • 另外,你的Status字段中没有包含你在函数中设置的OrderID字段。
  • 如评论中所提到的,你的json标签周围缺少了反引号。

一个合适的IDE会捕捉到这些错误。

英文:

Not sure it answers your question, but you may want to modify your model a little bit from :

type Status struct {
    Data struct {
        OrderId                   string    json:"orderId"
        DisputeStatus             string    json:"disputeStatus"
        DisputeCauseCategoryName  string    json:"disputeCauseCategoryName"
        ReverseLogisticCost         string        json:"ReverseLogisticCost"
        
    } json:"data"
    StatusJ string json:"status" 
}

To:

type Status struct {
    Data      Data      `json:"data"`
    StatusJ   string    `json:"status"`
}

type Data struct {
    OrderID                   string    `json:"orderId"`
    DisputeStatus             string    `json:"disputeStatus"`
    DisputeCauseCategoryName  string    `json:"disputeCauseCategoryName"`
    ReverseLogisticCost       string    `json:"reverseLogisticCost"`
}
  • Check the capital letter; in your example you had OrderId in your Data struct but status.Data.OrderID in your function.
  • Also your field Status does not contain an OrderID field which you were setting in your function.
  • As mentionned in comment, backticks were missing around your json tags.

A proper IDE would catch those.

答案4

得分: 0

OrderID更改为OrderId,根据mkopriva的建议,提前声明字段的类型:

package main

import (
	"fmt"
)

type StatusData struct {
	OrderId                  string `json:"orderId"`
	DisputeStatus            string `json:"disputeStatus"`
	DisputeCauseCategoryName string `json:"disputeCauseCategoryName"`
	ReverseLogisticCost      string `json:"ReverseLogisticCost"`
}

type Status struct {
	Data    StatusData
	StatusJ string
}

func main() {
	s := Status{Data: StatusData{OrderId: "123456"}}
	fmt.Println(s)
}

输出结果:

{{123456   } }
英文:

Change OrderID to OrderId,declare the field's type upfront as per suggestion of mkopriva:

package main

import (
	"fmt"
)

type StatusData struct {
	OrderId                  string `json:"orderId"`
	DisputeStatus            string `json:"disputeStatus"`
	DisputeCauseCategoryName string `json:"disputeCauseCategoryName"`
	ReverseLogisticCost      string `json:"ReverseLogisticCost"`
}

type Status struct {
	Data    StatusData
	StatusJ string
}

func main() {
	s := Status{Data: StatusData{OrderId: "123456"}}
	fmt.Println(s)
}

Output:

{{123456   } }

huangapple
  • 本文由 发表于 2021年9月12日 13:03:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/69148590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定