-1

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.

  • 1
    alternative to the answers below: https://go.dev/play/p/BEr4hSi20XJ – mkopriva Sep 10 '22 at 15:57
  • Thanks for the alternative. I think I agree with other folks that this does not seem the way to go, but if I did, your method seems obviously clearer than the direction I was heading. – wowzer Sep 10 '22 at 16:07
  • Not sure why I got a down votes. I know it's not groundbreaking stuff but I did search around and do not see an obvious duplicate... – wowzer Sep 10 '22 at 16:10
  • This is not a duplicate of any of the listed ones as none of those have an anon struct nested inside an anon struct which requires unique syntax. – wowzer Sep 10 '22 at 18:31

2 Answers2

2

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.

blami
  • 6,588
  • 2
  • 23
  • 31
  • ahh, I see. thank you very much! I agree it's not pretty. I was not really dead set on using this but did want to know where I had gone wrong either way. – wowzer Sep 10 '22 at 16:03
1

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.

melinda
  • 36
  • 2