Are nested anonymous structs possible in golang?

1.1k Views Asked by At

As I kind of loath the idea of creating a bunch of top level types for something used one time in one place, I am trying to create an anonymous struct nested inside an anonymous struct for a Json RPC call.

The anon struct would match the following non-anon types

type jsonRpcRequest struct {
    JsonRpc string `json:"jsonrpc"`
    Method  string `json:"method"`
    Id      string `json:"id"`
    Params  params `json:"params"`

}
type params struct {
    Format  string   `json:"format"`
    Cmds    []string `json:"cmds"`
    Version int      `json:"version"`
}

by doing the following

package main

func main() {
    data := struct {
        JsonRpc string `json:"jsonrpc"`
        Method  string `json:"method"`
        Id string `json:"id"`
        Params  struct {
            Format  string   `json:"format"`
            Cmds    []string `json:"cmds"`
            Version int      `json:"version"`
        } `json:"params"`
    }{
        JsonRpc: "2.0",
        Method:  "someMethod",
        Id:      "someId",
        Params: {
            Format:  "json",
            Cmds:    []string{"some", "list", "of", "commands"},
            Version: 1,
        },
    }
}

However I get the following error

./anon_struct_inside_anon_struct_example.go:17:11: missing type in composite literal

Is this even possible with golang syntax?

I cannot seem to get past the fact that golang wants to separate the type and value blocks so it seems there is no way to satisfy the compiler for the inner struct.

2

There are 2 best solutions below

0
melinda On

Yes, it is possible, but you must repeat the anonymous type in the composite literal:

data := struct {
    JsonRpc string `json:"jsonrpc"`
    Method  string `json:"method"`
    Id      string `json:"id"`
    Params  struct {
        Format  string   `json:"format"`
        Cmds    []string `json:"cmds"`
        Version int      `json:"version"`
    } `json:"params"`
}{
    JsonRpc: "2.0",
    Method:  "someMethod",
    Id:      "someId",
    Params: struct {
        Format  string   `json:"format"`
        Cmds    []string `json:"cmds"`
        Version int      `json:"version"`
    }{
        Format:  "json",
        Cmds:    []string{"some", "list", "of", "commands"},
        Version: 1,
    },
}

It's easier to declare the type.

1
blami On

To do this you need to tell compiler type of Params again in the literal:

    data := struct {
        JsonRpc string `json:"jsonrpc"`
        Method  string `json:"method"`
        Id      string `json:"id"`
        Params  struct {
            Format  string   `json:"format"`
            Cmds    []string `json:"cmds"`
            Version int      `json:"version"`
        } `json:"params"`
    }{
        JsonRpc: "2.0",
        Method:  "someMethod",
        Id:      "someId",
        Params: struct {
            Format  string   `json:"format"`
            Cmds    []string `json:"cmds"`
            Version int      `json:"version"`
        }{
            Format:  "json",
            Cmds:    []string{"some", "list", "of", "commands"},
            Version: 1,
        },
    }

As you can see it does not look nice and it is error prone for further edits. It probably makes more sense to just give Params type a name and reuse that, even if it is one-off.