This question already has answers here:
How to initialize a nested struct?
(10 answers)
Initialize nested struct definition
(3 answers)
Closed last year.
I have generated go struct from json.
And it gave me next output:
type PartnerBody87 struct {
Imp []struct {
Bidfloor float64 `json:"bidfloor"`
Secure int `json:"secure"`
Ext struct {
Type string `json:"type"`
Webpush int `json:"webpush"`
} `json:"ext"`
ID string `json:"id"`
Tagid string `json:"tagid"`
} `json:"imp"`
}
I tried different ways, and cannot find proper one of how to initiate the value for
Imp []struct.
Update:
I know that I can split struct into few types. But I'm curious if Go have ability to set everything in 1 struct - than how to use it?
You can split them like this:
type PartnerBody87 struct {
Imp []Imp `json:"imp"`
}
type Imp struct {
Bidfloor float64 `json:"bidfloor"`
Secure int `json:"secure"`
Ext Ext `json:"ext"`
ID string `json:"id"`
Tagid string `json:"tagid"`
}
type Ext struct {
Type string `json:"type"`
Webpush int `json:"webpush"`
}
Related
This question already has answers here:
How to initialize nested struct in golang?
(2 answers)
initializing a struct containing a slice of structs in golang
(2 answers)
Closed 10 months ago.
I have a nested struct like this:
type Project struct {
FolderStructure []FolderItem
Description string
}
type FolderItem struct {
SubFolderStructure []SubFolderItem
Description string
}
type SubFolderItem struct {
SubSubFolderStructure []SubSubFolderItem
Description string
}
type SubSubFolderItem struct {
Content string
Description string
}
I wonder how to initalize it, otherwise invalid memory address or nil pointer dereference will be thrown out.
Thanks in advance!
The easiest way to initialize is to create multiple instances as variables & then reuse them to assign the values to the nested structures.
Here is the working example: https://go.dev/play/p/6p3VFljyqom and same below, this is just one way of doing it and feel it's the easiest.
package main
import "fmt"
type Project struct {
FolderStructure []FolderItem
Description string
}
type FolderItem struct {
SubFolderStructure []SubFolderItem
Description string
}
type SubFolderItem struct {
SubSubFolderStructure []SubSubFolderItem
Description string
}
type SubSubFolderItem struct {
Content string
Description string
}
func main() {
ssfi1 := SubSubFolderItem{
"content1",
"description1 - SubSubFolderItem",
}
ssfi2 := SubSubFolderItem{
"content2",
"description2 - SubSubFolderItem",
}
sfi := SubFolderItem{
SubSubFolderStructure: []SubSubFolderItem{ssfi1, ssfi2},
Description: "description 1 - SubFolderItem",
}
fi := FolderItem{
SubFolderStructure: []SubFolderItem{sfi, sfi},
Description: "description 1 - FolderItem",
}
p := Project{
FolderStructure: []FolderItem{fi, fi},
Description: "description 1 - Project",
}
fmt.Println(ssfi1)
fmt.Println(ssfi2)
fmt.Println(sfi)
fmt.Println(fi)
fmt.Println(p)
}
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
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
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.
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.
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 } }
I'm trying to initialise this nested struct without success. Can anyone help me?
type ResultQuery struct {
Result []struct {
Process `json:"processes"`
Project `json:"project"`
}
}
type Project struct {
Units struct {
Distances string `json:"distances"`
} `json:"units"`
Name string `json:"name"`
}
type Process struct {
Status string `json:"status"`
StatusEvents []struct {
Time int64 `json:"time"`
} `json:"status_events"`
ID string `json:"_id"`
Type string `json:"type"`
Parameters struct {
Project string `json:"project"`
} `json:"parameters"`
}
Playground for my problem: https://play.golang.org/p/rVwEaxpkJGL
I have struct like
type SimpleBbInput struct {
MyInput struct {
Num struct {
val int
}
}
HisInput string
HerInput uint8
}
I will store the field name and type in a map[string]interface{}, result like
map[HerInput:uint8 MyInput:map[Num:map[val:int]] HisInput:string]
My question is how to using this map to get back SimpleBbInput without knowing this struct.
Thanks
I'm in the process of cleaning some code up and am trying to pass a slice value which is a struct to a function.
My struct looks like this:
type GetRecipesPaginatedResponse struct {
Total int `json:"total"`
PerPage int `json:"per_page"`
CurrentPage int `json:"current_page"`
LastPage int `json:"last_page"`
NextPageURL string `json:"next_page_url"`
PrevPageURL interface{} `json:"prev_page_url"`
From int `json:"from"`
To int `json:"to"`
Data []struct {
ID int `json:"id"`
ParentRecipeID int `json:"parent_recipe_id"`
UserID int `json:"user_id"`
Name string `json:"name"`
Description string `json:"description"`
IsActive bool `json:"is_active"`
IsPublic bool `json:"is_public"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
BjcpStyle struct {
SubCategoryID string `json:"sub_category_id"`
CategoryName string `json:"category_name"`
SubCategoryName string `json:"sub_category_name"`
} `json:"bjcp_style"`
UnitType struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"unit_type"`
} `json:"data"`
}
In my code, I fetch some JSON data from an API and get a response back that contains about 100 items in the Data slice.
I am then looping over each item in the Data slice and processing them.
As an example, it looks something like this:
for page := 1; page < 3; page++ {
newRecipes := getFromRecipesEndpoint(page, latestTimeStamp) //this returns an instance of GetRecipesPaginatedResponse
for _, newRecipe := range newRecipes.Data {
if rowExists(db, "SELECT id from community_recipes WHERE id=#id", sql.Named("id", newRecipe.ID)) {
insertIntoRecipes(db, true, newRecipe)
} else {
insertIntoRecipes(db, false, newRecipe)
}
}
}
So I am trying to pass the instance of a recipe to the insertIntoRecipes function, which looks like this:
func insertIntoRecipes(db *sql.DB, exists bool, newRecipe GetRecipesPaginatedResponse.Data) {
if exists {
//update the existing record in the DB
//perform some other updates with the information
} else {
//insert a new record into the DB
//insert some other information using this information
}
}
When I run this, I get the error:
GetRecipesPaginatedResponse.Data undefined (type GetRecipesPaginatedResponse has no method Data)
I can tell that the issue is to do with how I am trying to pass the newRecipe to the insertIntoRecipes function, newRecipe GetRecipesPaginatedResponse.Data, however I am not quite sure how to pass it in and declare the right variable type.
To pass an item inside the Data slice to a function, when I am looping over each item of the Data slice, how do I do that?
You cannot reference the anonymous type of the Data field using a field selector. The fix is to declare a named type for the Data field:
type GetRecipesPaginatedResponse struct {
...
Data []DataItem
...
}
type DataItem struct {
ID int `json:"id"`
ParentRecipeID int `json:"parent_recipe_id"`
UserID int `json:"user_id"`
Name string `json:"name"`
...
}
Use it like this:
func insertIntoRecipes(db *sql.DB, exists bool, newRecipe DataItem) {
...
}
There's probably a better name for DataItem.